#!/usr/bin/env python3 """ Generate one example image per Comfy App workflow and save to static/examples/. Uses the real comfy_apps functions + comfy_workflows_lib builders against nightmare. """ import os, sys, shutil, time, json from PIL import Image, ImageFilter, ImageDraw, ImageOps sys.path.insert(0, os.path.expanduser("~/auto-publisher/core")) import comfy_apps as CA import comfy_workflows_lib as CL BASE = os.path.expanduser("~/comfy-web") EXAMPLES = os.path.join(BASE, "static", "examples") os.makedirs(EXAMPLES, exist_ok=True) def upload(local, name): CL.upload_image(local, name=name) print(f" uploaded {name}") def save_result(app, local_path): if not local_path or not os.path.exists(local_path): print(f" [{app}] NO RESULT") return False ext = os.path.splitext(local_path)[1] or ".png" dest = os.path.join(EXAMPLES, app + ext) shutil.copy(local_path, dest) print(f" [{app}] -> {dest} ({os.path.getsize(dest)//1024} KB)") return True def gen(app, fn, **params): print(f"[{app}] building workflow...") wf = fn(**params) pid, err = CL.submit(wf) if err: print(f"[{app}] SUBMIT ERROR: {json.dumps(err)[:300]}") return None print(f"[{app}] pid={pid}, rendering...") paths = CL.fetch_result(pid, timeout=900) if not paths: print(f"[{app}] TIMEOUT/FAILED") return None save_result(app, paths[0]) return paths[0] # --------------------------------------------------------------------------- # free GPU first # --------------------------------------------------------------------------- print("freeing GPU (unload ollama, apply comfy OC)...") CL.free_gpu() time.sleep(2) results = {} # 1. Text-to-image bases print("\n=== BASE T2I ===") results["logo"] = gen("logo", CA.app_logo, prompt="minimalist geometric logo mark of a phoenix rising from flames, gold metallic on deep black, symmetrical vector emblem, clean lines, no text", steps=8) results["hero"] = gen("hero", CA.app_hero, prompt="epic cinematic fantasy landscape, floating islands with waterfalls at golden sunset, volumetric god rays, dramatic clouds, ultra detailed", steps=20) results["article"] = gen("article", CA.app_article, prompt="photorealistic over-the-shoulder shot of a barista pouring latte art in a sunlit cafe, shallow depth of field, morning light, editorial photography", steps=8) results["portrait"] = gen("portrait", CA.app_portrait, prompt="professional studio portrait of a woman in her 30s, soft window light, warm tones, sharp focus, 85mm, head and shoulders", steps=8) # upload base images to ComfyUI input/ for the derived apps print("\n=== UPLOADING BASES ===") names = {} for app, p in results.items(): if p and os.path.exists(p): n = f"base_{app}.png" upload(p, n) names[app] = n # make a low-res version of the portrait for upscale/restore_face demo lowres_path = None if results.get("portrait"): im = Image.open(results["portrait"]).convert("RGB") im = im.resize((192, 256), Image.LANCZOS) lowres_path = os.path.join(BASE, "uploads", "base_lowres.png") im.save(lowres_path) upload(lowres_path, "base_lowres.png") print(" created low-res portrait (192x256) for upscale demo") # make an inpaint mask (white blob on black) for the article image mask_path = os.path.join(BASE, "uploads", "inpaint_mask.png") if results.get("article"): a = Image.open(results["article"]) m = Image.new("L", a.size, 0) d = ImageDraw.Draw(m) w, h = a.size d.ellipse([w*0.35, h*0.25, w*0.75, h*0.75], fill=255) m.save(mask_path) upload(mask_path, "inpaint_mask.png") print(" created inpaint mask") # make a canny-ish control image from the article control_path = os.path.join(BASE, "uploads", "control_canny.png") if results.get("article"): a = Image.open(results["article"]).convert("L") e = a.filter(ImageFilter.FIND_EDGES) e = ImageOps.autocontrast(e) e.save(control_path) upload(control_path, "control_canny.png") print(" created control edge image") # 2. Derived apps print("\n=== DERIVED ===") if names.get("hero"): results["banner"] = gen("banner", CA.app_banner, image_name=names["hero"], prompt="epic cinematic fantasy landscape, floating islands, golden sunset, seamless extension", left=192, right=192, steps=25) if names.get("portrait"): results["outpaint"] = gen("outpaint", CA.app_outpaint, image_name=names["portrait"], prompt="extend the studio backdrop with soft bokeh lights, seamless", left=96, right=96, top=64, bottom=64, steps=25) if names.get("article") and os.path.exists(mask_path): results["inpaint"] = gen("inpaint", CA.app_inpaint, image_name=names["article"], mask_name="inpaint_mask.png", prompt="a glowing golden espresso machine with steam", steps=20, denoise=0.7) if lowres_path: results["upscale"] = gen("upscale", CA.app_upscale, image_name="base_lowres.png", upscaler="4x-UltraSharp.pth") results["restore_face"] = gen("restore_face", CA.app_restore_face, image_name="base_lowres.png", upscaler="RealESRGAN_x4.pth") if names.get("hero"): results["ipadapter"] = gen("ipadapter", CA.app_ipadapter, style_image=names["hero"], prompt="a cozy cottage by a lake at sunset, same painterly style", steps=20, cfg=7.0) if os.path.exists(control_path): results["controlnet"] = gen("controlnet", CA.app_controlnet, prompt="a detailed illustration of a barista in a cafe, line art", control_image="control_canny.png", control_type="canny", steps=20, cfg=7.0) if names.get("portrait"): try: results["face_swap"] = gen("face_swap", CA.app_face_swap, face_image=names["portrait"], prompt="a samurai warrior in full ornate armor, studio lighting, dramatic", steps=20) except Exception as e: print(f"[face_swap] ERROR: {e}") # restore GPU print("\nrestoring GPU (ollama OC profile)...") CL.restore_gpu() # summary print("\n=== SUMMARY ===") for app, p in results.items(): status = "OK" if (p and os.path.exists(p)) else "MISSING" print(f" {app:14s} {status}")