|
|
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)) |
|
|
|
|
|
|
|
|
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 |