Sugamdeol commited on
Commit
3d45539
·
verified ·
1 Parent(s): b70654b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -37
app.py CHANGED
@@ -4,13 +4,25 @@ from PIL import Image, ImageDraw, ImageFont
4
  import textwrap
5
  import os
6
  from concurrent.futures import ThreadPoolExecutor, as_completed
 
 
7
 
8
- def download_image(prompt, index):
 
 
 
 
 
 
 
 
 
9
  try:
10
- url = f"https://pollinations.ai/p/{prompt}"
11
- response = requests.get(url, timeout=10)
 
12
  response.raise_for_status()
13
- image_filename = f'generated_image_{index}.jpg'
14
  with open(image_filename, 'wb') as file:
15
  file.write(response.content)
16
  return image_filename
@@ -18,45 +30,38 @@ def download_image(prompt, index):
18
  print(f"Error downloading image {index}: {e}")
19
  return None
20
 
21
- def add_text_to_image(image_path, text):
22
  try:
23
  img = Image.open(image_path)
24
  draw = ImageDraw.Draw(img)
25
 
26
- # Use a default font if custom font is not available
27
  try:
28
- font = ImageFont.truetype("arial.ttf", 30)
29
  except IOError:
30
- font = ImageFont.load_default().font_variant(size=30)
31
 
32
- # Calculate text size and position
33
  img_width, img_height = img.size
34
- max_text_width = int(img_width * 0.9) # 90% of image width
35
  lines = textwrap.wrap(text, width=40)
36
 
37
- # Use getbbox instead of getsize
38
- line_height = font.getbbox("hg")[3] + 5 # Add some padding
39
  text_height = line_height * len(lines)
40
 
41
- # Create semi-transparent background
42
  overlay = Image.new('RGBA', img.size, (0, 0, 0, 0))
43
  overlay_draw = ImageDraw.Draw(overlay)
44
  overlay_draw.rectangle([(0, img_height - text_height - 20), (img_width, img_height)],
45
  fill=(0, 0, 0, 180))
46
 
47
- # Paste the overlay onto the original image
48
  img = img.convert('RGBA')
49
  img = Image.alpha_composite(img, overlay)
50
  draw = ImageDraw.Draw(img)
51
 
52
- # Add text
53
  y_text = img_height - text_height - 10
54
  for line in lines:
55
- # Use getbbox for line width calculation
56
  bbox = font.getbbox(line)
57
  line_width = bbox[2] - bbox[0]
58
  x_text = (img_width - line_width) / 2
59
- draw.text((x_text, y_text), line, font=font, fill=(255, 255, 255, 255))
60
  y_text += line_height
61
 
62
  img_with_text = f'text_added_{os.path.basename(image_path)}'
@@ -67,25 +72,15 @@ def add_text_to_image(image_path, text):
67
  print(f"Error adding text to image: {e}")
68
  return None
69
 
70
- with ThreadPoolExecutor(max_workers=5) as executor:
71
- future_to_idx = {executor.submit(process_line, idx, line): idx for idx, line in enumerate(lines)}
72
- for future in progress.tqdm(as_completed(future_to_idx), total=len(lines), desc="Processing images"):
73
- idx = future_to_idx[future]
74
- result = future.result()
75
- if result:
76
- images_with_text.append((idx, result))
77
-
78
- return [img for _, img in sorted(images_with_text)]
79
-
80
- def process_story_lines(story, progress=gr.Progress()):
81
  lines = [line.strip() for line in story.split('\n') if line.strip()]
82
  images_with_text = []
83
 
84
  def process_line(idx, line):
85
  prompt = line.replace(" ", "_")
86
- img_file = download_image(prompt, idx)
87
  if img_file:
88
- return add_text_to_image(img_file, line)
89
  return None
90
 
91
  with ThreadPoolExecutor(max_workers=5) as executor:
@@ -98,24 +93,60 @@ def process_story_lines(story, progress=gr.Progress()):
98
 
99
  return [img for _, img in sorted(images_with_text)]
100
 
101
- def visualize_story_images(story):
102
  if not story.strip():
103
  return []
104
- return process_story_lines(story)
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
- with gr.Blocks() as iface:
107
- gr.Markdown("# Story Visualizer")
108
 
109
  with gr.Row():
110
- story_input = gr.Textbox(lines=10, placeholder="Enter your story here...", label="Story Input")
111
- visualize_button = gr.Button("Visualize Story")
 
 
 
 
 
 
112
 
 
113
  gallery_output = gr.Gallery(label="Visualized Story", show_label=False, elem_id="gallery", columns=2, rows=2, height="auto")
114
 
 
 
 
 
 
 
115
  visualize_button.click(
116
  fn=visualize_story_images,
117
- inputs=[story_input],
118
  outputs=[gallery_output]
119
  )
120
 
 
 
 
 
 
 
 
 
 
 
 
121
  iface.launch(share=True)
 
4
  import textwrap
5
  import os
6
  from concurrent.futures import ThreadPoolExecutor, as_completed
7
+ import random
8
+ import time
9
 
10
+ # Constants for image styles
11
+ IMAGE_STYLES = {
12
+ "Realistic": "",
13
+ "Cartoon": "cartoon style",
14
+ "Watercolor": "watercolor painting style",
15
+ "Sketch": "pencil sketch style",
16
+ "Anime": "anime style"
17
+ }
18
+
19
+ def download_image(prompt, index, style):
20
  try:
21
+ style_prompt = f"{prompt}, {IMAGE_STYLES[style]}" if style != "Realistic" else prompt
22
+ url = f"https://pollinations.ai/p/{style_prompt.replace(' ', '_')}"
23
+ response = requests.get(url, timeout=15)
24
  response.raise_for_status()
25
+ image_filename = f'generated_image_{index}_{int(time.time())}.jpg'
26
  with open(image_filename, 'wb') as file:
27
  file.write(response.content)
28
  return image_filename
 
30
  print(f"Error downloading image {index}: {e}")
31
  return None
32
 
33
+ def add_text_to_image(image_path, text, font_size, text_color):
34
  try:
35
  img = Image.open(image_path)
36
  draw = ImageDraw.Draw(img)
37
 
 
38
  try:
39
+ font = ImageFont.truetype("arial.ttf", font_size)
40
  except IOError:
41
+ font = ImageFont.load_default().font_variant(size=font_size)
42
 
 
43
  img_width, img_height = img.size
44
+ max_text_width = int(img_width * 0.9)
45
  lines = textwrap.wrap(text, width=40)
46
 
47
+ line_height = font.getbbox("hg")[3] + 5
 
48
  text_height = line_height * len(lines)
49
 
 
50
  overlay = Image.new('RGBA', img.size, (0, 0, 0, 0))
51
  overlay_draw = ImageDraw.Draw(overlay)
52
  overlay_draw.rectangle([(0, img_height - text_height - 20), (img_width, img_height)],
53
  fill=(0, 0, 0, 180))
54
 
 
55
  img = img.convert('RGBA')
56
  img = Image.alpha_composite(img, overlay)
57
  draw = ImageDraw.Draw(img)
58
 
 
59
  y_text = img_height - text_height - 10
60
  for line in lines:
 
61
  bbox = font.getbbox(line)
62
  line_width = bbox[2] - bbox[0]
63
  x_text = (img_width - line_width) / 2
64
+ draw.text((x_text, y_text), line, font=font, fill=text_color)
65
  y_text += line_height
66
 
67
  img_with_text = f'text_added_{os.path.basename(image_path)}'
 
72
  print(f"Error adding text to image: {e}")
73
  return None
74
 
75
+ def process_story_lines(story, style, font_size, text_color, progress=gr.Progress()):
 
 
 
 
 
 
 
 
 
 
76
  lines = [line.strip() for line in story.split('\n') if line.strip()]
77
  images_with_text = []
78
 
79
  def process_line(idx, line):
80
  prompt = line.replace(" ", "_")
81
+ img_file = download_image(prompt, idx, style)
82
  if img_file:
83
+ return add_text_to_image(img_file, line, font_size, text_color)
84
  return None
85
 
86
  with ThreadPoolExecutor(max_workers=5) as executor:
 
93
 
94
  return [img for _, img in sorted(images_with_text)]
95
 
96
+ def visualize_story_images(story, style, font_size, text_color):
97
  if not story.strip():
98
  return []
99
+ return process_story_lines(story, style, font_size, text_color)
100
+
101
+ def preview_image(story, style, font_size, text_color):
102
+ if not story.strip():
103
+ return None
104
+ lines = [line.strip() for line in story.split('\n') if line.strip()]
105
+ if not lines:
106
+ return None
107
+ preview_line = random.choice(lines)
108
+ img_file = download_image(preview_line, 0, style)
109
+ if img_file:
110
+ return add_text_to_image(img_file, preview_line, font_size, text_color)
111
+ return None
112
 
113
+ with gr.Blocks(css="#gallery {height: 600px}") as iface:
114
+ gr.Markdown("# 📚✨ Story Visualizer")
115
 
116
  with gr.Row():
117
+ with gr.Column(scale=2):
118
+ story_input = gr.Textbox(lines=10, placeholder="Enter your story here...", label="Story Input")
119
+ with gr.Column(scale=1):
120
+ style_dropdown = gr.Dropdown(choices=list(IMAGE_STYLES.keys()), value="Realistic", label="Image Style")
121
+ font_size_slider = gr.Slider(minimum=20, maximum=60, value=30, step=2, label="Font Size")
122
+ text_color_picker = gr.ColorPicker(value="#FFFFFF", label="Text Color")
123
+ preview_button = gr.Button("Preview", variant="secondary")
124
+ visualize_button = gr.Button("Visualize Story", variant="primary")
125
 
126
+ preview_output = gr.Image(label="Preview", height=300)
127
  gallery_output = gr.Gallery(label="Visualized Story", show_label=False, elem_id="gallery", columns=2, rows=2, height="auto")
128
 
129
+ preview_button.click(
130
+ fn=preview_image,
131
+ inputs=[story_input, style_dropdown, font_size_slider, text_color_picker],
132
+ outputs=[preview_output]
133
+ )
134
+
135
  visualize_button.click(
136
  fn=visualize_story_images,
137
+ inputs=[story_input, style_dropdown, font_size_slider, text_color_picker],
138
  outputs=[gallery_output]
139
  )
140
 
141
+ gr.Markdown("""
142
+ ## How to use:
143
+ 1. Enter your story in the text box, with each line representing a scene.
144
+ 2. Choose an image style from the dropdown menu.
145
+ 3. Adjust the font size and text color as desired.
146
+ 4. Click "Preview" to see how a random scene from your story might look.
147
+ 5. When you're happy with the settings, click "Visualize Story" to generate images for all scenes.
148
+
149
+ Enjoy bringing your story to life! 🎨📖
150
+ """)
151
+
152
  iface.launch(share=True)