Spaces:
Running
Running
File size: 6,342 Bytes
db59f73 6fe13ea db59f73 6fe13ea db59f73 6fe13ea db59f73 6fe13ea af888c6 db59f73 af888c6 db59f73 | 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 | """
Generate the sample images shipped with the app as reference-node defaults.
They are produced by the studio's own txt2img pipeline rather than downloaded,
which keeps them licence-clean, on-brand, and β for the PNG Info sample β
genuinely carrying an embedded A1111 parameter block, so that pipeline
demonstrates a real round trip out of the box.
python apps/05_workflow1111/make_samples.py [--force]
"""
import json
import os
import shutil
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
for _s in (sys.stdout, sys.stderr):
try:
_s.reconfigure(encoding="utf-8", errors="replace")
except (AttributeError, ValueError):
pass
from PIL import Image # noqa: E402
import nodes as N # noqa: E402
HERE = os.path.dirname(os.path.abspath(__file__))
SAMPLES = os.path.join(HERE, "samples")
os.makedirs(SAMPLES, exist_ok=True)
# (filename, reference node it seeds, prompt, size, what it has to demonstrate)
SPECS = [
("init_image.jpg", "ref_init_image",
"a quiet wooden lakeside cabin at dawn, still water, pine forest, mist",
(768, 512), "img2img β something worth re-lighting or re-seasoning"),
("interrogate.jpg", "ref_interrogate_image",
"a rain-soaked neon street market at night, stalls, paper lanterns, "
"reflections on wet asphalt, crowded",
(768, 512), "interrogate β visually dense, lots for a VLM to name"),
("detect.jpg", "ref_detect_image",
"a photograph of a person walking a dog on a city pavement beside a "
"parked bicycle, a car in the background, daylight, documentary photo",
(768, 512), "detect β must contain real COCO classes"),
("extras.jpg", "ref_extras_image",
"studio portrait of a golden retriever sitting, plain light grey seamless "
"backdrop, soft key light, sharp focus",
(640, 640), "extras β a clean subject for upscaling and cutout"),
("control.jpg", "ref_control_image",
"an ornate victorian building facade, wrought iron balconies, tall "
"windows, intricate stonework, straight-on architectural photograph",
(768, 512), "annotator β hard structural edges for Canny"),
]
PNGINFO_PROMPT = ("a red fox curled asleep in deep snow, soft winter light, "
"shallow depth of field")
def shrink(img, box):
"""Fit inside `box` β samples ride in the repo, so keep them small."""
img = img.convert("RGB")
img.thumbnail(box, Image.LANCZOS)
return img
def save_jpg(img, path, quality=86):
img.save(path, format="JPEG", quality=quality, optimize=True,
progressive=True, subsampling=1)
return os.path.getsize(path)
def generate(prompt, width, height, seed):
out = N.txt2img(prompt, "blurry, watermark, text, low quality", 4, 1.0,
seed, width, height, "black-forest-labs/FLUX.1-schnell")
return N._load_image(out)
def main():
force = "--force" in sys.argv
manifest = {}
for i, (name, ref_id, prompt, box, why) in enumerate(SPECS):
path = os.path.join(SAMPLES, name)
if os.path.exists(path) and not force:
print(f" skip {name} (exists)")
manifest[ref_id] = name
continue
img = shrink(generate(prompt, box[0], box[1], 2000 + i * 37), box)
kb = save_jpg(img, path) // 1024
print(f" made {name:18} {img.width}Γ{img.height} {kb} KB β {why}")
manifest[ref_id] = name
# The PNG Info sample must carry a real embedded parameter block.
png = os.path.join(SAMPLES, "with_parameters.png")
if not os.path.exists(png) or force:
seed, steps, cfg, w, h = 987654321, 4, 1.0, 768, 512
img = shrink(generate(PNGINFO_PROMPT, w, h, seed), (768, 512))
info = N.generation_info(PNGINFO_PROMPT, "blurry, watermark, text",
steps, cfg, seed, img.width, img.height,
"black-forest-labs/FLUX.1-schnell")
stamped = N.postprocess(N._emit(img), 1, "Lanczos", 0, 1, 1, 1, 0, 0, 0, "", info)
# Quantize to a 256-colour palette before shipping. This sample has to
# stay PNG (a JPEG cannot carry the `parameters` text chunk), and a
# full-colour 768Γ512 photo PNG is ~471 KB β slow enough over the Hub
# (~4.8s) that the reference node looks broken while it loads. The
# palette version is ~161 KB and keeps the text chunk and the
# dimensions, so the embedded `Size:` still matches the image.
from PIL import PngImagePlugin
full = Image.open(stamped["path"])
full.load()
meta = PngImagePlugin.PngInfo()
for key, value in (full.info or {}).items():
if isinstance(value, str):
meta.add_text(key, value)
quantized = full.convert("RGB").quantize(
colors=256, method=Image.MEDIANCUT, dither=Image.FLOYDSTEINBERG)
quantized.save(png, format="PNG", optimize=True, pnginfo=meta)
print(f" made with_parameters.png {os.path.getsize(png)//1024} KB "
"β PNG Info, with a real embedded parameter block")
manifest["ref_pnginfo_image"] = "with_parameters.png"
with open(os.path.join(SAMPLES, "manifest.json"), "w", encoding="utf-8") as f:
json.dump(manifest, f, indent=2)
# --- verify the samples actually do their job -------------------------
print("\nverifying:")
det = json.loads(__import__("gradio.workflow", fromlist=["x"]).call_model(
["facebook/detr-resnet-50", "object_detection",
json.dumps({"image": {"path": os.path.join(SAMPLES, "detect.jpg")}}),
__import__("huggingface_hub").get_token(), "auto"]))
labels = sorted({d["label"] for d in det[0]} if isinstance(det[0], list) else set())
print(f" detect.jpg β DETR finds: {labels or 'NOTHING (bad sample)'}")
report, fields_json = N.png_info(png)
fields = json.loads(fields_json)
ok = fields.get("prompt", "").startswith("a red fox curled")
print(f" with_parameters.png β embedded params readable: {ok} "
f"(seed={fields.get('seed')}, size={fields.get('size')})")
total = sum(os.path.getsize(os.path.join(SAMPLES, f))
for f in os.listdir(SAMPLES))
print(f"\n samples/ total: {total // 1024} KB")
if __name__ == "__main__":
main()
|