iran-bank-cards-ocr
Version:
A TypeScript library to detect Iranian bank names, logos, and validate card numbers using OCR and Luhn algorithm.
79 lines (78 loc) • 3.61 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateCardNumber = validateCardNumber;
exports.detectBankInfo = detectBankInfo;
exports.preprocessImage = preprocessImage;
const banks_1 = require("./banks");
/**
* Validate a card number using the Luhn algorithm.
* @param {string} cardNumber - The card number to validate.
* @returns {boolean} True if the card number is valid, otherwise false.
*/
function validateCardNumber(cardNumber) {
const digits = cardNumber.split('').map(Number);
let sum = 0;
for (let i = 0; i < digits.length; i++) {
let digit = digits[digits.length - 1 - i];
if (i % 2 === 1) {
digit *= 2;
if (digit > 9)
digit -= 9;
}
sum += digit;
}
return sum % 10 === 0;
}
/**
* Detect the bank info (name and logo) based on the card number's prefix.
* @param {string} cardNumber - The card number.
* @returns {{ en: string; fa: string; logo: string } | null} The bank info (name in English, Persian, and logo URL) or null if not recognized.
*/
function detectBankInfo(cardNumber) {
const prefix = cardNumber.substring(0, 4);
return banks_1.banks[prefix] || null;
}
/**
* Preprocess the image by cropping and resizing it.
* @param {string} imageDataUrl - The image data URL.
* @returns {Promise<string>} A promise that resolves to the processed image data URL.
*/
function preprocessImage(imageDataUrl) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = imageDataUrl;
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Crop the image to focus on the card area (adjust as needed)
const cropWidth = img.width * 0.8;
const cropHeight = img.height * 0.5;
canvas.width = cropWidth;
canvas.height = cropHeight;
ctx.drawImage(img, (img.width - cropWidth) / 2, // Center the crop
(img.height - cropHeight) / 2, // Center the crop
cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);
// Resize the image for better OCR accuracy
const resizedCanvas = document.createElement('canvas');
const resizedCtx = resizedCanvas.getContext('2d');
resizedCanvas.width = 800; // Adjust as needed
resizedCanvas.height = 600; // Adjust as needed
resizedCtx.drawImage(canvas, 0, 0, resizedCanvas.width, resizedCanvas.height);
resolve(resizedCanvas.toDataURL('image/jpeg'));
};
img.onerror = (error) => {
reject(new Error(`Error loading image: ${error}`));
};
});
});
}