from flask import Flask, request, jsonify from flask_cors import CORS from passporteye import read_mrz from PIL import Image import numpy as np import cv2 import io import base64 import json from datetime import datetime app = Flask(__name__) # تفعيل CORS للسماح للفرونت إند بالوصول للباك إند CORS(app, resources={r"/api/*": {"origins": "*"}}) def crop_mrz_region(image): """قص منطقة MRZ تلقائياً (الـ 35% السفلي من الصورة)""" img_array = np.array(image) height, width = img_array.shape[:2] mrz_height = int(height * 0.35) y_start = height - mrz_height cropped = img_array[y_start:height, :] return Image.fromarray(cropped) def enhance_mrz_image(image): """تحسين جودة صورة MRZ باستخدام OpenCV""" img_array = np.array(image) # تحويل لرمادي if len(img_array.shape) == 3: gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY) else: gray = img_array # تقليل الضوضاء denoised = cv2.fastNlMeansDenoising(gray) # تحسين التباين clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) enhanced = clahe.apply(denoised) # تحويل لصورة ثنائية (Black & White) لسهولة القراءة _, binary = cv2.threshold(enhanced, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) return Image.fromarray(binary) def image_to_base64(image): """تحويل الصورة إلى نص Base64 للعرض في المتصفح""" # تصغير الصورة قليلاً لتسريع النقل إذا كانت ضخمة max_size = 800 if max(image.size) > max_size: image.thumbnail((max_size, max_size), Image.Resampling.LANCZOS) buffered = io.BytesIO() image.save(buffered, format="PNG") img_str = base64.b64encode(buffered.getvalue()).decode() return img_str @app.route('/api/process-passport', methods=['POST']) def process_passport(): try: if 'image' not in request.files: return jsonify({'success': False, 'error': 'لم يتم استلام صورة'}), 400 file = request.files['image'] image = Image.open(file.stream).convert('RGB') # 1. قص منطقة الـ MRZ mrz_cropped = crop_mrz_region(image) # 2. تحسين الصورة mrz_enhanced = enhance_mrz_image(mrz_cropped) # 3. حفظ في Buffer للقراءة بواسطة PassportEye img_buffer = io.BytesIO() mrz_enhanced.save(img_buffer, format='PNG') img_buffer.seek(0) # 4. استخراج البيانات start_time = datetime.now() mrz = read_mrz(img_buffer) processing_time = (datetime.now() - start_time).total_seconds() if mrz is None: return jsonify({'success': False, 'error': 'فشل في قراءة منطقة MRZ. حاول تصوير منطقة السطرين السفليين بوضوح.'}), 422 mrz_data = mrz.to_dict() mrz_data['walltime'] = processing_time # 5. تجهيز الصور للفرونت إند images_response = { 'original': image_to_base64(image), 'cropped': image_to_base64(mrz_cropped), 'enhanced': image_to_base64(mrz_enhanced) } return jsonify({ 'success': True, 'data': mrz_data, 'images': images_response }) except Exception as e: print(f"Error: {str(e)}") return jsonify({'success': False, 'error': str(e)}), 500 if __name__ == '__main__': # استخدام المنفذ الذي توفره المنصة أو 7860 (الافتراضي لـ Hugging Face) import os port = int(os.environ.get('PORT', 7860)) app.run(host='0.0.0.0', port=port)