Spaces:
Runtime error
Runtime error
File size: 5,916 Bytes
dc2831e 269525c 0483ea7 7690d86 3d45539 dc2831e 3d45539 7690d86 3d45539 7690d86 3d45539 7690d86 dc2831e 3d45539 7690d86 7d205dd 0063f85 3d45539 0063f85 3d45539 7d205dd 3d45539 7d205dd 412ae09 3d45539 7d205dd 412ae09 7d205dd 3d45539 7d205dd 7690d86 7d205dd 7690d86 269525c 3d45539 b70654b 3d45539 b70654b 3d45539 b70654b 3d45539 7690d86 3d45539 0483ea7 3d45539 7690d86 3d45539 7690d86 3d45539 0063f85 7690d86 3d45539 7690d86 3d45539 7690d86 dc2831e 3d45539 a6146e8 |
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 140 141 142 143 144 145 146 147 148 149 150 151 152 |
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) |