// 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;