LeafCat79 commited on
Commit
30dc2ff
·
verified ·
1 Parent(s): bc1d515

Fix gallery image outputs

Browse files
Files changed (1) hide show
  1. app.py +52 -16
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import base64
2
  import io
3
  import re
 
4
  import time
5
  from dataclasses import dataclass
6
  from html import escape
@@ -8,7 +9,7 @@ from urllib.parse import quote
8
 
9
  import gradio as gr
10
  import requests
11
- from PIL import Image
12
 
13
 
14
  POLLINATIONS_URL = (
@@ -118,25 +119,45 @@ def parse_assets(raw_roles: str, style_hint: str) -> list[AssetSpec]:
118
  return specs
119
 
120
 
121
- def image_to_data_uri(content: bytes, width: int, height: int) -> str:
122
  image = Image.open(io.BytesIO(content)).convert("RGBA")
123
  image = image.resize((width, height), Image.LANCZOS)
124
  out = io.BytesIO()
125
  image.save(out, format="PNG")
126
- return "data:image/png;base64," + base64.b64encode(out.getvalue()).decode("ascii")
127
 
128
 
129
- def placeholder_data_uri(role: str, width: int, height: int) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  label = escape(role[:18])
131
- svg = f"""<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}">
132
- <rect width="100%" height="100%" fill="#222"/>
133
- <rect x="4" y="4" width="{width - 8}" height="{height - 8}" rx="12" fill="#3b82f6"/>
134
- <text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" fill="white" font-family="Arial" font-size="18">{label}</text>
135
- </svg>"""
136
- return "data:image/svg+xml;base64," + base64.b64encode(svg.encode("utf-8")).decode("ascii")
 
 
 
 
 
137
 
138
 
139
- def generate_asset(spec: AssetSpec, index: int) -> tuple[str, str | None]:
140
  seed = abs(hash((spec.role, spec.prompt, index))) % 999999
141
  url = POLLINATIONS_URL.format(
142
  prompt=quote(spec.prompt),
@@ -149,13 +170,28 @@ def generate_asset(spec: AssetSpec, index: int) -> tuple[str, str | None]:
149
  try:
150
  response = requests.get(url, timeout=120)
151
  response.raise_for_status()
152
- return image_to_data_uri(response.content, spec.width, spec.height), None
 
 
 
 
 
153
  except Exception as exc:
154
  if attempt < 2:
155
  time.sleep(8)
156
  else:
157
- return placeholder_data_uri(spec.role, spec.width, spec.height), str(exc)
158
- return placeholder_data_uri(spec.role, spec.width, spec.height), "Unknown generation error"
 
 
 
 
 
 
 
 
 
 
159
 
160
 
161
  def replacement_names(spec: AssetSpec) -> set[str]:
@@ -235,9 +271,9 @@ def generate_images_and_game(html_code: str, roles: str, style_hint: str):
235
  errors = []
236
 
237
  for index, spec in enumerate(specs):
238
- data_uri, error = generate_asset(spec, index)
239
  assets[spec.role] = data_uri
240
- gallery.append((data_uri, f"{spec.role} -> {spec.filename}"))
241
  if error:
242
  errors.append(f"{spec.role}: fallback used ({error})")
243
 
 
1
  import base64
2
  import io
3
  import re
4
+ import tempfile
5
  import time
6
  from dataclasses import dataclass
7
  from html import escape
 
9
 
10
  import gradio as gr
11
  import requests
12
+ from PIL import Image, ImageDraw, ImageFont
13
 
14
 
15
  POLLINATIONS_URL = (
 
119
  return specs
120
 
121
 
122
+ def image_to_png_bytes(content: bytes, width: int, height: int) -> bytes:
123
  image = Image.open(io.BytesIO(content)).convert("RGBA")
124
  image = image.resize((width, height), Image.LANCZOS)
125
  out = io.BytesIO()
126
  image.save(out, format="PNG")
127
+ return out.getvalue()
128
 
129
 
130
+ def png_bytes_to_data_uri(content: bytes) -> str:
131
+ return "data:image/png;base64," + base64.b64encode(content).decode("ascii")
132
+
133
+
134
+ def write_gallery_image(content: bytes, role: str) -> str:
135
+ handle = tempfile.NamedTemporaryFile(
136
+ prefix=f"{slugify(role)}_",
137
+ suffix=".png",
138
+ delete=False,
139
+ )
140
+ handle.write(content)
141
+ handle.close()
142
+ return handle.name
143
+
144
+
145
+ def placeholder_png_bytes(role: str, width: int, height: int) -> bytes:
146
  label = escape(role[:18])
147
+ image = Image.new("RGBA", (width, height), "#222222")
148
+ draw = ImageDraw.Draw(image)
149
+ draw.rounded_rectangle((4, 4, width - 4, height - 4), radius=12, fill="#3b82f6")
150
+ font = ImageFont.load_default()
151
+ bbox = draw.textbbox((0, 0), label, font=font)
152
+ x = (width - (bbox[2] - bbox[0])) / 2
153
+ y = (height - (bbox[3] - bbox[1])) / 2
154
+ draw.text((x, y), label, fill="white", font=font)
155
+ out = io.BytesIO()
156
+ image.save(out, format="PNG")
157
+ return out.getvalue()
158
 
159
 
160
+ def generate_asset(spec: AssetSpec, index: int) -> tuple[str, str, str | None]:
161
  seed = abs(hash((spec.role, spec.prompt, index))) % 999999
162
  url = POLLINATIONS_URL.format(
163
  prompt=quote(spec.prompt),
 
170
  try:
171
  response = requests.get(url, timeout=120)
172
  response.raise_for_status()
173
+ png_content = image_to_png_bytes(response.content, spec.width, spec.height)
174
+ return (
175
+ png_bytes_to_data_uri(png_content),
176
+ write_gallery_image(png_content, spec.role),
177
+ None,
178
+ )
179
  except Exception as exc:
180
  if attempt < 2:
181
  time.sleep(8)
182
  else:
183
+ png_content = placeholder_png_bytes(spec.role, spec.width, spec.height)
184
+ return (
185
+ png_bytes_to_data_uri(png_content),
186
+ write_gallery_image(png_content, spec.role),
187
+ str(exc),
188
+ )
189
+ png_content = placeholder_png_bytes(spec.role, spec.width, spec.height)
190
+ return (
191
+ png_bytes_to_data_uri(png_content),
192
+ write_gallery_image(png_content, spec.role),
193
+ "Unknown generation error",
194
+ )
195
 
196
 
197
  def replacement_names(spec: AssetSpec) -> set[str]:
 
271
  errors = []
272
 
273
  for index, spec in enumerate(specs):
274
+ data_uri, gallery_path, error = generate_asset(spec, index)
275
  assets[spec.role] = data_uri
276
+ gallery.append((gallery_path, f"{spec.role} -> {spec.filename}"))
277
  if error:
278
  errors.append(f"{spec.role}: fallback used ({error})")
279