Spaces:
Sleeping
Sleeping
File size: 5,281 Bytes
fbfdc25 f52a68c fbfdc25 79e5b91 a29ec48 9e08a6d fbfdc25 f52a68c 9e08a6d 65c3bfa 54ab095 a29ec48 54ab095 35b1a5a 54ab095 35b1a5a 54ab095 fbfdc25 65c3bfa 19de2fe fbfdc25 65c3bfa a29ec48 dfae7ec 65c3bfa dfae7ec 65c3bfa fbfdc25 65c3bfa dfae7ec 65c3bfa dfae7ec 65c3bfa f52a68c 65c3bfa dfae7ec 65c3bfa a29ec48 65c3bfa a29ec48 65c3bfa a29ec48 65c3bfa a29ec48 65c3bfa dfae7ec 65c3bfa a29ec48 65c3bfa a29ec48 65c3bfa fbfdc25 f52a68c fbfdc25 a29ec48 f52a68c fbfdc25 a29ec48 fbfdc25 9e08a6d fbfdc25 a29ec48 54ab095 fbfdc25 9e08a6d a29ec48 35b1a5a fbfdc25 35b1a5a 9e08a6d 54ab095 fbfdc25 dfae7ec | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | import gradio as gr
from PIL import Image, ImageDraw, ImageFont
import arabic_reshaper
from bidi.algorithm import get_display
import requests
from io import BytesIO
import os
# Your COLOR_MAP dictionary remains the same
COLOR_MAP = {
"Black": (0, 0, 0),
"White": (255, 255, 255),
"Gray": (128, 128, 128),
"Red": (255, 0, 0),
"Blue": (0, 0, 255),
}
# --- REVISED AND FINAL FUNCTION ---
def overlay_text_on_image(persian_text, url, upload, username, text_color):
# --- Stage 1: Image Loading (No changes) ---
if url and url.strip():
if not url.startswith(('http://', 'https://')):
url = 'https://' + url
try:
response = requests.get(url)
response.raise_for_status()
img = Image.open(BytesIO(response.content))
except Exception as e:
raise ValueError(f"Failed to load image from URL: {e}")
elif upload:
img = Image.open(upload)
else:
raise ValueError("Please provide either an image URL or upload an image.")
img = img.resize((1080, 1080), Image.LANCZOS)
draw = ImageDraw.Draw(img)
width, height = img.size
# --- Stage 2: Font and Color Setup (No changes) ---
font_path = "Vazir.ttf"
if not os.path.exists(font_path):
print("Warning: Vazirmatn font not found. Falling back to default.")
possible_fonts = [
"Vazir.ttf",
"/usr/share/fonts/truetype/noto/NotoNaskhArabic-Regular.ttf",
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
]
font_path = next((f for f in possible_fonts if os.path.exists(f)), "DejaVuSans.ttf")
selected_color = COLOR_MAP.get(text_color, (0, 0, 0))
lines = [line for line in persian_text.split('\n') if line.strip()]
reshaped_lines = [arabic_reshaper.reshape(line) for line in lines]
# --- Stage 3: UNIFORM FONT SIZE CALCULATION (No changes in logic) ---
initial_font_size = 80
max_width = width * 0.90
uniform_font_size = initial_font_size
longest_line = ""
if reshaped_lines:
temp_font = ImageFont.truetype(font_path, uniform_font_size)
longest_line = max(reshaped_lines, key=lambda line: draw.textlength(line, font=temp_font))
while uniform_font_size > 20:
font = ImageFont.truetype(font_path, uniform_font_size)
if draw.textlength(longest_line, font=font) <= max_width:
break
uniform_font_size -= 2
final_font = ImageFont.truetype(font_path, uniform_font_size)
# --- Stage 4: Text Block Height Calculation and Centering ---
line_spacing = 20
total_text_height = 0
line_heights = []
for line in reshaped_lines:
# *** THE ONLY CHANGE IS ON THIS LINE ***
# Replaced getbbox with textbbox for older Pillow compatibility
line_bbox = draw.textbbox((0, 0), line, font=final_font)
line_height = line_bbox[3] - line_bbox[1]
line_heights.append(line_height)
total_text_height += line_height
total_text_height += (len(reshaped_lines) - 1) * line_spacing if len(reshaped_lines) > 1 else 0
y_start = (height - total_text_height) / 2
# --- Stage 5: Drawing the Text ---
current_y = y_start
for i, line in enumerate(reshaped_lines):
x_center = width / 2
line_y_center = current_y + line_heights[i] / 2
draw.text(
(x_center, line_y_center),
line,
font=final_font,
fill=selected_color,
anchor="mm"
)
current_y += line_heights[i] + line_spacing
# --- Stage 6: Username Drawing (No changes) ---
username_font_size = 40
username_font = ImageFont.truetype(font_path, username_font_size)
display_username = get_display(arabic_reshaper.reshape(f"@{username}"))
username_x = width / 2
username_y = height - 50
draw.text((username_x, username_y), display_username, font=username_font, fill=selected_color, anchor="mb")
return img
# --- Your Gradio Interface Code (No changes needed here) ---
with gr.Blocks() as demo:
gr.Markdown("# Persian Quote Overlay for Instagram Posts")
gr.Markdown("Paste an image URL from another HF Space or upload an image, enter Persian text (quote, supports multi-line), choose text color, and username. The app overlays the text centered with dynamic font sizing and places the username at the bottom center.")
with gr.Row():
persian_text = gr.Textbox(label="Persian Quote Text (Multi-line supported)", lines=5)
image_input = gr.Textbox(label="Image URL (e.g., from another HF Space)")
username = gr.Textbox(label="Channel Username (e.g., mychannel)")
with gr.Row():
text_color = gr.Dropdown(label="Text Color", choices=list(COLOR_MAP.keys()), value="Black")
image_upload = gr.Image(label="Optional: Upload Image (if not using URL)", type="filepath")
output_image = gr.Image(label="Output Image")
submit_btn = gr.Button("Generate Overlay")
submit_btn.click(overlay_text_on_image,
inputs=[persian_text, image_input, image_upload, username, text_color],
outputs=output_image)
demo.launch()
|