Sugamdeol's picture
Update app.py
3d45539 verified
raw
history blame
5.92 kB
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)