from PIL import Image, ImageDraw, ImageFont import os import arabic_reshaper from bidi.algorithm import get_display import cv2 import numpy as np def preprocess_image(image_path): """معالجة مسبقة للصورة لتحسين جودة OCR""" try: # قراءة الصورة image = cv2.imread(image_path) if image is None: return image_path # تحويل إلى تدرج الرمادي gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # زيادة التباين enhanced = cv2.convertScaleAbs(gray, alpha=1.5, beta=30) # إزالة الضوضاء denoised = cv2.medianBlur(enhanced, 3) # حفظ الصورة المحسنة enhanced_path = "enhanced_image.png" cv2.imwrite(enhanced_path, denoised) return enhanced_path except Exception as e: print(f"❌ خطأ في معالجة الصورة: {e}") return image_path def get_font(config): """الحصول على خط مناسب للغة العربية""" font_path = config.get("font_path", "fonts/arabic-font.ttf") font_size = config.get("font_size", 20) try: # محاولة تحميل الخط المحدد return ImageFont.truetype(font_path, font_size) except: try: # محاولة استخدام خط افتراضي للعربية return ImageFont.truetype("arial.ttf", font_size) except: try: # استخدام خط النظام إذا توفر return ImageFont.load_default() except: # الخط الافتراضي إذا فشل كل شيء return None def render_text(image_path, boxes, texts, save_path="output.png", config=None): """إعادة رسم النصوص المترجمة على الصورة""" if config is None: config = {} try: # فتح الصورة im = Image.open(image_path).convert("RGBA") draw = ImageDraw.Draw(im) # الحصول على الخط font = get_font(config) # رسم كل نص في المربع المناسب for box, text in zip(boxes, texts): if not text or text == "[نص غير معروف]": # تخطي النصوص الفارغة continue # معالجة النص العربي للعرض الصحيح reshaped_text = arabic_reshaper.reshape(text) bidi_text = get_display(reshaped_text) # حساب مركز المربع x_coords = [point[0] for point in box] y_coords = [point[1] for point in box] x_center = sum(x_coords) / len(x_coords) y_center = sum(y_coords) / len(y_coords) # حساب حجم النص if font: bbox = draw.textbbox((0, 0), bidi_text, font=font) text_width = bbox[2] - bbox[0] text_height = bbox[3] - bbox[1] else: text_width = len(text) * 10 # تقدير تقريبي text_height = 20 # حساب موضع النص (مركز المربع) x_pos = x_center - text_width / 2 y_pos = y_center - text_height / 2 # التأكد من أن النص داخل حدود الصورة x_pos = max(10, min(x_pos, im.width - text_width - 10)) y_pos = max(10, min(y_pos, im.height - text_height - 10)) # رسم خلفية semi-transparent للنص if font: bbox = draw.textbbox((x_pos, y_pos), bidi_text, font=font) draw.rectangle(bbox, fill=(255, 255, 255, 200)) # رسم النص if font: draw.text((x_pos, y_pos), bidi_text, fill=(0, 0, 0), font=font) else: draw.text((x_pos, y_pos), bidi_text, fill=(0, 0, 0)) # حفظ الصورة الناتجة im.save(save_path) print(f"✅ تم حفظ الصورة في: {save_path}") except Exception as e: print(f"❌ خطأ في إعادة الرسم: {e}") raise