import gradio as gr from PIL import Image, ImageDraw, ImageFont import random # Set default banner size for LinkedIn BANNER_WIDTH = 1584 BANNER_HEIGHT = 396 # Use a common system font (change if needed) FONT_PATH = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" # --- AI-like Suggestions --- sample_texts = [ "Open to Work", "UX Designer", "Data Scientist", "Product Manager", "Software Engineer", "AI Researcher", ] def suggest_text(): return random.choice(sample_texts) # --- Handle Click --- click_position = [None, None] def record_click(evt: gr.SelectData): global click_position click_position = [evt.index[0], evt.index[1]] return f"[{click_position[0]}, {click_position[1]}]" # --- Generate Banner with Overlaid Text --- def generate_banner(image, text, font_size, color): if image is None: print("No image uploaded.") return None # Resize to LinkedIn banner size image = image.resize((BANNER_WIDTH, BANNER_HEIGHT)) if not click_position or None in click_position: print("Click position not set.") return image draw = ImageDraw.Draw(image) try: font = ImageFont.truetype(FONT_PATH, font_size) except Exception as e: print("Font loading failed:", e) font = ImageFont.load_default() draw.text((click_position[0], click_position[1]), text, fill=color, font=font) return image # --- Gradio UI --- with gr.Blocks() as demo: gr.Markdown("🧰 **Job Banner Creator (LinkedIn-Ready)**") with gr.Row(): with gr.Column(): image_input = gr.Image(label="Upload Background Image", type="pil") # image_input.style(height=300) with gr.Column(): click_display = gr.Textbox(label="Click Position") with gr.Row(): text_input = gr.Textbox(label="Custom Text (e.g. 'Open to Work')") suggest_btn = gr.Button("🎯 Suggest Text") with gr.Row(): font_size_slider = gr.Slider(20, 120, step=1, value=48, label="Font Size") text_color = gr.ColorPicker(label="Text Color", value="#000000") generate_btn = gr.Button("✅ Generate Banner") output_image = gr.Image(label="Preview (1584 x 396)") # Events suggest_btn.click(fn=suggest_text, outputs=text_input) image_input.select(fn=record_click, outputs=click_display) generate_btn.click(fn=generate_banner, inputs=[image_input, text_input, font_size_slider, text_color], outputs=output_image) # --- Launch --- demo.launch()