Sugamdeol's picture
Update app.py
3d45539 verified
import gradio as gr
import requests
from PIL import Image, ImageDraw, ImageFont
import textwrap
import os
from concurrent.futures import ThreadPoolExecutor, as_completed
import random
import time
# Constants for image styles
IMAGE_STYLES = {
"Realistic": "",
"Cartoon": "cartoon style",
"Watercolor": "watercolor painting style",
"Sketch": "pencil sketch style",
"Anime": "anime style"
}
def download_image(prompt, index, style):
try:
style_prompt = f"{prompt}, {IMAGE_STYLES[style]}" if style != "Realistic" else prompt
url = f"https://pollinations.ai/p/{style_prompt.replace(' ', '_')}"
response = requests.get(url, timeout=15)
response.raise_for_status()
image_filename = f'generated_image_{index}_{int(time.time())}.jpg'
with open(image_filename, 'wb') as file:
file.write(response.content)
return image_filename
except requests.RequestException as e:
print(f"Error downloading image {index}: {e}")
return None
def add_text_to_image(image_path, text, font_size, text_color):
try:
img = Image.open(image_path)
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype("arial.ttf", font_size)
except IOError:
font = ImageFont.load_default().font_variant(size=font_size)
img_width, img_height = img.size
max_text_width = int(img_width * 0.9)
lines = textwrap.wrap(text, width=40)
line_height = font.getbbox("hg")[3] + 5
text_height = line_height * len(lines)
overlay = Image.new('RGBA', img.size, (0, 0, 0, 0))
overlay_draw = ImageDraw.Draw(overlay)
overlay_draw.rectangle([(0, img_height - text_height - 20), (img_width, img_height)],
fill=(0, 0, 0, 180))
img = img.convert('RGBA')
img = Image.alpha_composite(img, overlay)
draw = ImageDraw.Draw(img)
y_text = img_height - text_height - 10
for line in lines:
bbox = font.getbbox(line)
line_width = bbox[2] - bbox[0]
x_text = (img_width - line_width) / 2
draw.text((x_text, y_text), line, font=font, fill=text_color)
y_text += line_height
img_with_text = f'text_added_{os.path.basename(image_path)}'
img = img.convert('RGB')
img.save(img_with_text)
return img_with_text
except Exception as e:
print(f"Error adding text to image: {e}")
return None
def process_story_lines(story, style, font_size, text_color, progress=gr.Progress()):
lines = [line.strip() for line in story.split('\n') if line.strip()]
images_with_text = []
def process_line(idx, line):
prompt = line.replace(" ", "_")
img_file = download_image(prompt, idx, style)
if img_file:
return add_text_to_image(img_file, line, font_size, text_color)
return None
with ThreadPoolExecutor(max_workers=5) as executor:
future_to_idx = {executor.submit(process_line, idx, line): idx for idx, line in enumerate(lines)}
for future in progress.tqdm(as_completed(future_to_idx), total=len(lines), desc="Processing images"):
idx = future_to_idx[future]
result = future.result()
if result:
images_with_text.append((idx, result))
return [img for _, img in sorted(images_with_text)]
def visualize_story_images(story, style, font_size, text_color):
if not story.strip():
return []
return process_story_lines(story, style, font_size, text_color)
def preview_image(story, style, font_size, text_color):
if not story.strip():
return None
lines = [line.strip() for line in story.split('\n') if line.strip()]
if not lines:
return None
preview_line = random.choice(lines)
img_file = download_image(preview_line, 0, style)
if img_file:
return add_text_to_image(img_file, preview_line, font_size, text_color)
return None
with gr.Blocks(css="#gallery {height: 600px}") as iface:
gr.Markdown("# πŸ“šβœ¨ Story Visualizer")
with gr.Row():
with gr.Column(scale=2):
story_input = gr.Textbox(lines=10, placeholder="Enter your story here...", label="Story Input")
with gr.Column(scale=1):
style_dropdown = gr.Dropdown(choices=list(IMAGE_STYLES.keys()), value="Realistic", label="Image Style")
font_size_slider = gr.Slider(minimum=20, maximum=60, value=30, step=2, label="Font Size")
text_color_picker = gr.ColorPicker(value="#FFFFFF", label="Text Color")
preview_button = gr.Button("Preview", variant="secondary")
visualize_button = gr.Button("Visualize Story", variant="primary")
preview_output = gr.Image(label="Preview", height=300)
gallery_output = gr.Gallery(label="Visualized Story", show_label=False, elem_id="gallery", columns=2, rows=2, height="auto")
preview_button.click(
fn=preview_image,
inputs=[story_input, style_dropdown, font_size_slider, text_color_picker],
outputs=[preview_output]
)
visualize_button.click(
fn=visualize_story_images,
inputs=[story_input, style_dropdown, font_size_slider, text_color_picker],
outputs=[gallery_output]
)
gr.Markdown("""
## How to use:
1. Enter your story in the text box, with each line representing a scene.
2. Choose an image style from the dropdown menu.
3. Adjust the font size and text color as desired.
4. Click "Preview" to see how a random scene from your story might look.
5. When you're happy with the settings, click "Visualize Story" to generate images for all scenes.
Enjoy bringing your story to life! πŸŽ¨πŸ“–
""")
iface.launch(share=True)