Akhmad123 commited on
Commit
95e967f
ยท
verified ยท
1 Parent(s): 44b2e07

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -84
app.py CHANGED
@@ -1,5 +1,4 @@
1
  import gradio as gr
2
- import json
3
  from datetime import datetime
4
  from fpdf import FPDF
5
  import os
@@ -32,16 +31,10 @@ USER_DB = {
32
  # ============================
33
  # HELPERS
34
  # ============================
35
- def normalize(v, default=""):
36
- if not v:
37
- return default
38
- return str(v).strip()
39
-
40
  def safe_text(text):
41
- return ''.join(c if 32 <= ord(c) <= 126 else ' ' for c in text)
42
-
43
- def now_iso():
44
- return datetime.utcnow().isoformat() + "Z"
45
 
46
  def ensure_outputs_dir():
47
  os.makedirs("outputs", exist_ok=True)
@@ -98,86 +91,66 @@ def generate_comic_panels(goal, style, tone, chapter_title, panels=PANELS_PER_CH
98
  # VISUAL PROMPT GENERATOR
99
  # ============================
100
  def convert_panel_to_visual_prompt(panel_text, character_mode, character_desc):
101
- """
102
- Mengubah teks panel menjadi prompt visual pastel cartoon.
103
- """
104
  base_style = (
105
  "Cute pastel cartoon illustration, soft colors, round shapes, kid-friendly, "
106
  "Islamic-friendly, simple background, environmental setting, high quality."
107
  )
108
-
109
  if character_mode == "Custom" and character_desc.strip():
110
  return f"{base_style} Featuring: {character_desc}. Scene: {panel_text}."
111
-
112
  return f"{base_style} Scene: {panel_text}."
113
 
114
  # ============================
115
- # IMAGE GENERATORS (3 MODEL)
116
  # ============================
117
- def generate_image_pastel_mix(prompt):
118
- """
119
- fofr/pastel-mix โ€” paling cocok untuk komik pastel
120
- """
121
- try:
122
- out = replicate.run(
123
- "fofr/pastel-mix",
124
- input={"prompt": prompt}
125
- )
126
- if isinstance(out, list) and out:
127
- return out[0]
128
- except:
129
- return ""
130
- return ""
131
 
132
- def generate_image_sdxl(prompt):
133
- """
134
- stability-ai/sdxl โ€” detail tinggi
135
- """
136
- try:
137
- out = replicate.run(
138
- "stability-ai/sdxl",
139
- input={
140
- "prompt": prompt,
141
- "cfg_scale": 7,
142
- "steps": 30
143
- }
144
- )
145
- if isinstance(out, dict) and "output" in out and out["output"]:
146
- return out["output"][0]
147
- if isinstance(out, list) and out:
148
- return out[0]
149
- except:
150
- return ""
151
- return ""
152
 
153
- def generate_image_flux(prompt):
154
- """
155
- black-forest-labs/flux-schnell-free โ€” cepat, tapi tidak selalu stabil
156
- """
157
  try:
158
- out = replicate.run(
159
- "black-forest-labs/flux-schnell-free",
160
- input={"prompt": prompt}
161
- )
162
  if isinstance(out, list) and out:
163
  return out[0]
164
- except:
 
 
 
 
 
 
 
165
  return ""
166
  return ""
167
 
168
  def generate_image_by_model(prompt, model_name):
169
- """
170
- Pilih model berdasarkan dropdown user.
171
- """
172
- if model_name == "Pastel-Mix":
173
- return generate_image_pastel_mix(prompt)
174
- elif model_name == "SDXL":
175
- return generate_image_sdxl(prompt)
176
- elif model_name == "Flux":
177
- return generate_image_flux(prompt)
178
- else:
179
  # fallback ke Pastel-Mix
180
- return generate_image_pastel_mix(prompt)
 
 
 
 
 
 
181
 
182
  def download_image(url, filename):
183
  if not url:
@@ -190,7 +163,7 @@ def download_image(url, filename):
190
  with open(path, "wb") as f:
191
  f.write(r.content)
192
  return path
193
- except:
194
  return ""
195
 
196
  # ============================
@@ -266,42 +239,34 @@ def build_comic_pdf(username, goal, genre, tone, style, cover_brief,
266
  pdf.cell(0, 10, safe_text(ch), 0, 1)
267
  pdf.ln(4)
268
 
269
- # Generate panels
270
  panels_text = generate_comic_panels(goal, style, tone, ch, PANELS_PER_CHAPTER)
271
 
272
  for p_idx, panel in enumerate(panels_text, start=1):
273
-
274
- # Visual prompt
275
  visual_prompt = convert_panel_to_visual_prompt(
276
  panel,
277
  character_mode,
278
  character_desc
279
  )
280
 
281
- # Generate image by selected model
282
  illus_url = generate_image_by_model(visual_prompt, image_model)
283
  illus_path = download_image(
284
  illus_url,
285
  f"chapter_{idx}_panel_{p_idx}_{uuid.uuid4().hex}.png"
286
  )
287
 
288
- # Panel title
289
  pdf.set_font("Helvetica", "B", 12)
290
  pdf.cell(0, 8, safe_text(f"Panel {p_idx}"), 0, 1)
291
  pdf.ln(1)
292
 
293
- # Image
294
  if illus_path:
295
  y_start = pdf.get_y()
296
  pdf.image(illus_path, x=20, y=y_start, w=170)
297
  pdf.set_y(y_start + 80)
298
 
299
- # Text
300
  pdf.set_font("Helvetica", "", 11)
301
  pdf.multi_cell(180, 6, safe_text(panel), 0)
302
  pdf.ln(3)
303
 
304
- # OUTPUT FILE
305
  if comic_name.strip():
306
  filename = os.path.join("outputs", f"{comic_name}.pdf")
307
  else:
@@ -338,7 +303,7 @@ with gr.Blocks() as demo:
338
  # MAIN UI
339
  with gr.Group(visible=False) as main_ui:
340
 
341
- gr.Markdown("# ๐ŸŒŸ AIPromptLab โ€” Comic Generator 2.1 (Cartoon Pastel Edition)")
342
 
343
  with gr.Tabs():
344
 
@@ -395,7 +360,6 @@ with gr.Blocks() as demo:
395
  value="Cute pastel cartoon cover of Islamic children adventure."
396
  )
397
 
398
- # CHARACTER MODE
399
  character_mode = gr.Dropdown(
400
  label="Mode Karakter",
401
  choices=["Otomatis", "Custom"],
@@ -416,11 +380,11 @@ with gr.Blocks() as demo:
416
  [character_desc]
417
  )
418
 
419
- # IMAGE MODEL DROPDOWN
420
  image_model = gr.Dropdown(
421
  label="Model Gambar",
422
- choices=["Pastel-Mix", "SDXL", "Flux"],
423
- value="Pastel-Mix" # default sesuai pilihanmu
424
  )
425
 
426
  generate_pdf_btn = gr.Button("๐Ÿš€ Generate Comic PDF")
 
1
  import gradio as gr
 
2
  from datetime import datetime
3
  from fpdf import FPDF
4
  import os
 
31
  # ============================
32
  # HELPERS
33
  # ============================
 
 
 
 
 
34
  def safe_text(text):
35
+ if not text:
36
+ return ""
37
+ return ''.join(c if 32 <= ord(c) <= 126 else ' ' for c in str(text))
 
38
 
39
  def ensure_outputs_dir():
40
  os.makedirs("outputs", exist_ok=True)
 
91
  # VISUAL PROMPT GENERATOR
92
  # ============================
93
  def convert_panel_to_visual_prompt(panel_text, character_mode, character_desc):
 
 
 
94
  base_style = (
95
  "Cute pastel cartoon illustration, soft colors, round shapes, kid-friendly, "
96
  "Islamic-friendly, simple background, environmental setting, high quality."
97
  )
 
98
  if character_mode == "Custom" and character_desc.strip():
99
  return f"{base_style} Featuring: {character_desc}. Scene: {panel_text}."
 
100
  return f"{base_style} Scene: {panel_text}."
101
 
102
  # ============================
103
+ # IMAGE MODEL ROUTER (16 MODEL)
104
  # ============================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
+ MODEL_MAP = {
107
+ # Nama pendek -> ID model Replicate
108
+ "Pastel-Mix": "fofr/pastel-mix",
109
+ "SDXL": "stability-ai/sdxl",
110
+ "Flux Schnell": "black-forest-labs/flux-schnell",
111
+ "Flux Schnell Free": "black-forest-labs/flux-schnell-free",
112
+ "Flux Pro": "black-forest-labs/flux-1.1-pro",
113
+ "Flux Max": "black-forest-labs/flux-1.1-max",
114
+ "Flux Dev": "black-forest-labs/flux-1.1-dev",
115
+ "Flux Flex": "black-forest-labs/flux-1.1-flex",
116
+ "Seedream 4.5": "bytedance/seedream-4.5",
117
+ "Seedream 5 Lite": "bytedance/seedream-5-lite",
118
+ "Ideogram Turbo": "ideogram-ai/ideogram-v3-turbo",
119
+ "Ideogram Balanced": "ideogram-ai/ideogram-v3-balanced",
120
+ "Ideogram Quality": "ideogram-ai/ideogram-v3-quality",
121
+ "Recraft V4": "recraft-ai/recraft-v4",
122
+ "Recraft V4 SVG": "recraft-ai/recraft-v4-svg",
123
+ "Imagen Fast": "google/imagen-4-fast",
124
+ }
 
125
 
126
+ def generate_image_generic(model_id, prompt):
 
 
 
127
  try:
128
+ out = replicate.run(model_id, input={"prompt": prompt})
129
+ # Beberapa model mengembalikan list, beberapa dict
 
 
130
  if isinstance(out, list) and out:
131
  return out[0]
132
+ if isinstance(out, dict):
133
+ # coba beberapa kemungkinan key umum
134
+ for key in ["output", "image", "images"]:
135
+ if key in out and out[key]:
136
+ if isinstance(out[key], list):
137
+ return out[key][0]
138
+ return out[key]
139
+ except Exception:
140
  return ""
141
  return ""
142
 
143
  def generate_image_by_model(prompt, model_name):
144
+ model_id = MODEL_MAP.get(model_name)
145
+ if not model_id:
 
 
 
 
 
 
 
 
146
  # fallback ke Pastel-Mix
147
+ model_id = MODEL_MAP["Pastel-Mix"]
148
+ url = generate_image_generic(model_id, prompt)
149
+ if not url:
150
+ # fallback kedua: Pastel-Mix
151
+ if model_name != "Pastel-Mix":
152
+ url = generate_image_generic(MODEL_MAP["Pastel-Mix"], prompt)
153
+ return url
154
 
155
  def download_image(url, filename):
156
  if not url:
 
163
  with open(path, "wb") as f:
164
  f.write(r.content)
165
  return path
166
+ except Exception:
167
  return ""
168
 
169
  # ============================
 
239
  pdf.cell(0, 10, safe_text(ch), 0, 1)
240
  pdf.ln(4)
241
 
 
242
  panels_text = generate_comic_panels(goal, style, tone, ch, PANELS_PER_CHAPTER)
243
 
244
  for p_idx, panel in enumerate(panels_text, start=1):
 
 
245
  visual_prompt = convert_panel_to_visual_prompt(
246
  panel,
247
  character_mode,
248
  character_desc
249
  )
250
 
 
251
  illus_url = generate_image_by_model(visual_prompt, image_model)
252
  illus_path = download_image(
253
  illus_url,
254
  f"chapter_{idx}_panel_{p_idx}_{uuid.uuid4().hex}.png"
255
  )
256
 
 
257
  pdf.set_font("Helvetica", "B", 12)
258
  pdf.cell(0, 8, safe_text(f"Panel {p_idx}"), 0, 1)
259
  pdf.ln(1)
260
 
 
261
  if illus_path:
262
  y_start = pdf.get_y()
263
  pdf.image(illus_path, x=20, y=y_start, w=170)
264
  pdf.set_y(y_start + 80)
265
 
 
266
  pdf.set_font("Helvetica", "", 11)
267
  pdf.multi_cell(180, 6, safe_text(panel), 0)
268
  pdf.ln(3)
269
 
 
270
  if comic_name.strip():
271
  filename = os.path.join("outputs", f"{comic_name}.pdf")
272
  else:
 
303
  # MAIN UI
304
  with gr.Group(visible=False) as main_ui:
305
 
306
+ gr.Markdown("# ๐ŸŒŸ AIPromptLab โ€” Comic Generator 2.3 (Multi Model Image)")
307
 
308
  with gr.Tabs():
309
 
 
360
  value="Cute pastel cartoon cover of Islamic children adventure."
361
  )
362
 
 
363
  character_mode = gr.Dropdown(
364
  label="Mode Karakter",
365
  choices=["Otomatis", "Custom"],
 
380
  [character_desc]
381
  )
382
 
383
+ # IMAGE MODEL DROPDOWN (16 MODEL, Aโ€“Z)
384
  image_model = gr.Dropdown(
385
  label="Model Gambar",
386
+ choices=sorted(list(MODEL_MAP.keys())),
387
+ value="Pastel-Mix"
388
  )
389
 
390
  generate_pdf_btn = gr.Button("๐Ÿš€ Generate Comic PDF")