242 lines
7.7 KiB
JavaScript
242 lines
7.7 KiB
JavaScript
|
|
// const express = require('express');
|
||
|
|
// const multer = require('multer');
|
||
|
|
// const path = require('path');
|
||
|
|
// const fs = require('fs');
|
||
|
|
// const sharp = require('sharp');
|
||
|
|
// const tesseract = require('tesseract.js');
|
||
|
|
// const axios = require('axios');
|
||
|
|
|
||
|
|
|
||
|
|
// const router = express.Router();
|
||
|
|
|
||
|
|
// // Create the upload folder if it doesn't exist
|
||
|
|
// const uploadPath = path.join(__dirname, "../uploads/pan");
|
||
|
|
// if (!fs.existsSync(uploadPath)) {
|
||
|
|
// fs.mkdirSync(uploadPath, { recursive: true });
|
||
|
|
// }
|
||
|
|
|
||
|
|
// // Set up multer storage
|
||
|
|
// const storage = multer.diskStorage({
|
||
|
|
// destination: function (req, file, cb) {
|
||
|
|
// cb(null, uploadPath);
|
||
|
|
// },
|
||
|
|
// filename: function (req, file, cb) {
|
||
|
|
// const uniqueName = `${Date.now()}-${file.originalname}`;
|
||
|
|
// cb(null, uniqueName);
|
||
|
|
// }
|
||
|
|
// });
|
||
|
|
|
||
|
|
// // Accept only one file with field name 'panImage'
|
||
|
|
// const upload = multer({
|
||
|
|
// storage: storage,
|
||
|
|
// limits: { fileSize: 5 * 1024 * 1024 }, // 5MB max
|
||
|
|
// }).single('panImage');
|
||
|
|
|
||
|
|
// // Preprocess the image (convert to grayscale and increase contrast)
|
||
|
|
// async function preprocessImage(imagePath) {
|
||
|
|
// const outputPath = imagePath.replace('.jpeg', '-processed.jpeg'); // New path for the processed image
|
||
|
|
|
||
|
|
// await sharp(imagePath)
|
||
|
|
// .resize(800) // Resize the image for better OCR accuracy
|
||
|
|
// .grayscale() // Convert to grayscale
|
||
|
|
// .normalize() // Enhance contrast
|
||
|
|
// .toFile(outputPath);
|
||
|
|
|
||
|
|
// return outputPath;
|
||
|
|
// }
|
||
|
|
|
||
|
|
// router.post('/api/verify-pan', (req, res) => {
|
||
|
|
// upload(req, res, async function (err) {
|
||
|
|
// if (err instanceof multer.MulterError) {
|
||
|
|
// console.error('Multer error:', err);
|
||
|
|
// return res.status(400).json({ error: 'Multer error', detail: err.message });
|
||
|
|
// } else if (err) {
|
||
|
|
// console.error('Unknown error:', err);
|
||
|
|
// return res.status(500).json({ error: 'Unknown error', detail: err.message });
|
||
|
|
// }
|
||
|
|
|
||
|
|
// if (!req.file) {
|
||
|
|
// return res.status(400).json({ error: 'No PAN image uploaded' });
|
||
|
|
// }
|
||
|
|
|
||
|
|
// const { pan } = req.body;
|
||
|
|
// if (!pan) {
|
||
|
|
// return res.status(400).json({ error: 'PAN number is required' });
|
||
|
|
// }
|
||
|
|
|
||
|
|
|
||
|
|
// console.log('Received PAN:', pan);
|
||
|
|
// console.log('Saved file path:', req.file.path);
|
||
|
|
|
||
|
|
// try {
|
||
|
|
// // Preprocess the image
|
||
|
|
// const processedImagePath = await preprocessImage(req.file.path);
|
||
|
|
|
||
|
|
// // Run OCR on the preprocessed image
|
||
|
|
// const { data: { text } } = await tesseract.recognize(
|
||
|
|
// processedImagePath,
|
||
|
|
// 'eng', // English language
|
||
|
|
// {
|
||
|
|
// logger: (m) => console.log(m),
|
||
|
|
// }
|
||
|
|
// );
|
||
|
|
|
||
|
|
// console.log('Extracted text from image:', text);
|
||
|
|
|
||
|
|
// if (!text || text.trim().length === 0) {
|
||
|
|
// return res.status(400).json({ error: 'Failed to extract text from image' });
|
||
|
|
// }
|
||
|
|
|
||
|
|
// // Clean up extracted text and PAN number
|
||
|
|
// const cleanedExtractedText = text.replace(/\s+/g, '').toUpperCase();
|
||
|
|
// const cleanedPanNumber = pan.replace(/\s+/g, '').toUpperCase();
|
||
|
|
|
||
|
|
// const matchedPANs = cleanedExtractedText.match(/[A-Z]{5}[0-9]{4}[A-Z]/g) || [];
|
||
|
|
|
||
|
|
// console.log("Extracted PAN candidates:", matchedPANs);
|
||
|
|
|
||
|
|
// if (matchedPANs.includes(cleanedPanNumber)) {
|
||
|
|
// return res.status(200).json({
|
||
|
|
// verified: true,
|
||
|
|
// message: 'PAN verified successfully',
|
||
|
|
// pan,
|
||
|
|
// imageUrl: `/uploads/pan/${req.file.filename}`,
|
||
|
|
// });
|
||
|
|
// } else {
|
||
|
|
// return res.status(400).json({
|
||
|
|
// error: true,
|
||
|
|
// verified: false,
|
||
|
|
// message: 'PAN mismatch',
|
||
|
|
// pan,
|
||
|
|
// imageUrl: `/uploads/pan/${req.file.filename}`,
|
||
|
|
// });
|
||
|
|
// }
|
||
|
|
// } catch (error) {
|
||
|
|
// console.error('Error during OCR:', error);
|
||
|
|
// return res.status(500).json({ error: 'Error during OCR', detail: error.message });
|
||
|
|
// }
|
||
|
|
// });
|
||
|
|
// });
|
||
|
|
|
||
|
|
// module.exports = router;
|
||
|
|
|
||
|
|
const express = require('express');
|
||
|
|
const multer = require('multer');
|
||
|
|
const path = require('path');
|
||
|
|
const fs = require('fs');
|
||
|
|
const sharp = require('sharp');
|
||
|
|
const tesseract = require('tesseract.js');
|
||
|
|
const router = express.Router();
|
||
|
|
|
||
|
|
// Create the upload folder if it doesn't exist
|
||
|
|
const uploadPath = path.join(__dirname, "../uploads/pan");
|
||
|
|
if (!fs.existsSync(uploadPath)) {
|
||
|
|
fs.mkdirSync(uploadPath, { recursive: true });
|
||
|
|
}
|
||
|
|
|
||
|
|
// Set up multer storage
|
||
|
|
const storage = multer.diskStorage({
|
||
|
|
destination: function (req, file, cb) {
|
||
|
|
cb(null, uploadPath); // Destination folder for uploaded files
|
||
|
|
},
|
||
|
|
filename: function (req, file, cb) {
|
||
|
|
const uniqueName = `${Date.now()}-${file.originalname}`;
|
||
|
|
cb(null, uniqueName); // Store files with a unique name
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// Accept only one file with the field name 'panImage'
|
||
|
|
const upload = multer({
|
||
|
|
storage: storage,
|
||
|
|
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB max
|
||
|
|
}).single('panImage');
|
||
|
|
|
||
|
|
// Preprocess the image (convert to grayscale and enhance contrast)
|
||
|
|
async function preprocessImage(imagePath) {
|
||
|
|
const outputPath = imagePath.replace('.jpeg', '-processed.jpeg'); // Processed image path
|
||
|
|
await sharp(imagePath)
|
||
|
|
.resize(800) // Resize image for better OCR accuracy
|
||
|
|
.grayscale() // Convert to grayscale
|
||
|
|
.normalize() // Enhance contrast
|
||
|
|
.toFile(outputPath); // Save processed image
|
||
|
|
|
||
|
|
return outputPath;
|
||
|
|
}
|
||
|
|
|
||
|
|
// PAN verification API endpoint
|
||
|
|
router.post('/api/verify-pan', (req, res) => {
|
||
|
|
upload(req, res, async function (err) {
|
||
|
|
// Handle multer errors
|
||
|
|
if (err instanceof multer.MulterError) {
|
||
|
|
console.error('Multer error:', err);
|
||
|
|
return res.status(400).json({ error: 'Multer error', detail: err.message });
|
||
|
|
} else if (err) {
|
||
|
|
console.error('Unknown error:', err);
|
||
|
|
return res.status(500).json({ error: 'Unknown error', detail: err.message });
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!req.file) {
|
||
|
|
return res.status(400).json({ error: 'No PAN image uploaded' });
|
||
|
|
}
|
||
|
|
|
||
|
|
const { pan } = req.body;
|
||
|
|
if (!pan) {
|
||
|
|
return res.status(400).json({ error: 'PAN number is required' });
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log('Received PAN:', pan);
|
||
|
|
console.log('Saved file path:', req.file.path);
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Preprocess the image before running OCR
|
||
|
|
const processedImagePath = await preprocessImage(req.file.path);
|
||
|
|
|
||
|
|
// Run OCR to extract text from the image
|
||
|
|
const { data: { text } } = await tesseract.recognize(
|
||
|
|
processedImagePath,
|
||
|
|
'eng', // Use English for OCR
|
||
|
|
{
|
||
|
|
logger: (m) => console.log(m), // Optional: log progress
|
||
|
|
}
|
||
|
|
);
|
||
|
|
|
||
|
|
console.log('Extracted text from image:', text);
|
||
|
|
|
||
|
|
// Ensure the extracted text is valid
|
||
|
|
if (!text || text.trim().length === 0) {
|
||
|
|
return res.status(400).json({ error: 'Failed to extract text from image' });
|
||
|
|
}
|
||
|
|
|
||
|
|
// Clean up extracted text and compare with the provided PAN number
|
||
|
|
const cleanedExtractedText = text.replace(/\s+/g, '').toUpperCase();
|
||
|
|
const cleanedPanNumber = pan.replace(/\s+/g, '').toUpperCase();
|
||
|
|
|
||
|
|
const matchedPANs = cleanedExtractedText.match(/[A-Z]{5}[0-9]{4}[A-Z]/g) || [];
|
||
|
|
|
||
|
|
console.log("Extracted PAN candidates:", matchedPANs);
|
||
|
|
|
||
|
|
// Check if the extracted PAN matches the provided PAN
|
||
|
|
if (matchedPANs.includes(cleanedPanNumber)) {
|
||
|
|
return res.status(200).json({
|
||
|
|
verified: true,
|
||
|
|
message: 'PAN verified successfully',
|
||
|
|
pan,
|
||
|
|
imageUrl: `/uploads/pan/${req.file.filename}`,
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
return res.status(400).json({
|
||
|
|
verified: false,
|
||
|
|
message: 'PAN mismatch',
|
||
|
|
pan,
|
||
|
|
imageUrl: `/uploads/pan/${req.file.filename}`,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error during OCR:', error);
|
||
|
|
return res.status(500).json({ error: 'Error during OCR', detail: error.message });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
module.exports = router;
|