Spaces:
Running on Zero
Running on Zero
Improve generated image sharpness
Browse files
app.py
CHANGED
|
@@ -80,8 +80,8 @@ FOREGROUND_MODEL_REVISION = os.environ.get(
|
|
| 80 |
"FOREGROUND_MODEL_REVISION",
|
| 81 |
"e2bf8e4460fc8fa32bba5ea4d94b3233d367b0e4",
|
| 82 |
)
|
| 83 |
-
PRIMARY_IMAGE_STEPS = int(os.environ.get("PRIMARY_IMAGE_STEPS", "
|
| 84 |
-
PRIMARY_SPRITE_STEPS = int(os.environ.get("PRIMARY_SPRITE_STEPS", "
|
| 85 |
PRIMARY_SPRITE_ATTEMPTS = max(1, int(os.environ.get("PRIMARY_SPRITE_ATTEMPTS", "3")))
|
| 86 |
PRIMARY_GUIDANCE_SCALE = float(os.environ.get("PRIMARY_GUIDANCE_SCALE", "1.5"))
|
| 87 |
USE_PRIMARY_IMAGE_MODEL = os.environ.get("USE_PRIMARY_IMAGE_MODEL", "1") == "1"
|
|
@@ -1764,17 +1764,17 @@ def diffusion_negative_prompt(spec: AssetSpec) -> str:
|
|
| 1764 |
}.get(spec.camera, "")
|
| 1765 |
if spec.composition in {"single_subject", "icon", "animation_frame"}:
|
| 1766 |
return (
|
| 1767 |
-
"multiple subjects, duplicate character,
|
| 1768 |
-
"
|
| 1769 |
-
"
|
| 1770 |
-
"
|
| 1771 |
+ camera_negative
|
| 1772 |
)
|
| 1773 |
if spec.composition == "seamless":
|
| 1774 |
-
return "visible seams, borders, frame, perspective mockup, text, watermark" + camera_negative
|
| 1775 |
if spec.composition == "sprite_sheet":
|
| 1776 |
-
return "irregular grid, overlapping cells, labels, text, watermark" + camera_negative
|
| 1777 |
-
return "text, labels, watermark, presentation mockup" + camera_negative
|
| 1778 |
|
| 1779 |
|
| 1780 |
def build_camera_control_image(spec: AssetSpec, width: int = 1024, height: int = 576) -> Image.Image:
|
|
@@ -1924,19 +1924,20 @@ def primary_diffusion_prompt(spec: AssetSpec) -> str:
|
|
| 1924 |
variation = f"Variation: {compact_prompt_words(spec.variation, 4)}. " if spec.variation else ""
|
| 1925 |
subject = (spec.group or spec.role).replace("_", " ")
|
| 1926 |
return (
|
| 1927 |
-
f"{camera} Single isolated {subject} subject. One complete body
|
| 1928 |
-
"Fill
|
|
|
|
| 1929 |
"Plain uniform white field only; no environment, scenery, ground plane, or surrounding border. "
|
| 1930 |
f"{variation}{description}"
|
| 1931 |
)
|
| 1932 |
description = compact_prompt_words(spec.prompt, 26 if variation else 34)
|
| 1933 |
composition = {
|
| 1934 |
-
"icon": "Exactly one centered readable game icon, uniform white field.",
|
| 1935 |
-
"animation_frame": "Exactly one isolated animation frame subject at stable scale, uniform white field.",
|
| 1936 |
-
"full_frame": "One complete edge-to-edge game image filling the canvas.",
|
| 1937 |
-
"seamless": "One seamless edge-to-edge repeating game-art tile.",
|
| 1938 |
-
"sprite_sheet": "One deliberately organized regular-grid sprite sheet.",
|
| 1939 |
-
"freeform": "One user-defined game image following the requested composition exactly.",
|
| 1940 |
}[spec.composition]
|
| 1941 |
return f"{camera} {composition} {variation}{description}"
|
| 1942 |
|
|
@@ -2131,12 +2132,16 @@ def polish_diffusion_asset(image: Image.Image, spec: AssetSpec) -> bytes:
|
|
| 2131 |
def polish_neural_cutout(image: Image.Image, spec: AssetSpec) -> bytes:
|
| 2132 |
"""Resize and normalize a neural alpha cutout without changing its generated RGB art."""
|
| 2133 |
contained = image.convert("RGBA")
|
| 2134 |
-
contained.thumbnail((spec.width, spec.height), Image.LANCZOS)
|
| 2135 |
-
canvas = Image.new("RGBA", (spec.width, spec.height), (0, 0, 0, 0))
|
| 2136 |
-
offset = ((spec.width - contained.width) // 2, (spec.height - contained.height) // 2)
|
| 2137 |
-
canvas.alpha_composite(contained, dest=offset)
|
| 2138 |
if spec.composition in {"single_subject", "icon", "animation_frame"}:
|
| 2139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2140 |
out = io.BytesIO()
|
| 2141 |
canvas.save(out, format="PNG")
|
| 2142 |
return out.getvalue()
|
|
|
|
| 80 |
"FOREGROUND_MODEL_REVISION",
|
| 81 |
"e2bf8e4460fc8fa32bba5ea4d94b3233d367b0e4",
|
| 82 |
)
|
| 83 |
+
PRIMARY_IMAGE_STEPS = int(os.environ.get("PRIMARY_IMAGE_STEPS", "6"))
|
| 84 |
+
PRIMARY_SPRITE_STEPS = int(os.environ.get("PRIMARY_SPRITE_STEPS", "8"))
|
| 85 |
PRIMARY_SPRITE_ATTEMPTS = max(1, int(os.environ.get("PRIMARY_SPRITE_ATTEMPTS", "3")))
|
| 86 |
PRIMARY_GUIDANCE_SCALE = float(os.environ.get("PRIMARY_GUIDANCE_SCALE", "1.5"))
|
| 87 |
USE_PRIMARY_IMAGE_MODEL = os.environ.get("USE_PRIMARY_IMAGE_MODEL", "1") == "1"
|
|
|
|
| 1764 |
}.get(spec.camera, "")
|
| 1765 |
if spec.composition in {"single_subject", "icon", "animation_frame"}:
|
| 1766 |
return (
|
| 1767 |
+
"multiple subjects, duplicate character, repeated subject, character sheet, turnaround, lineup, alternate views, "
|
| 1768 |
+
"multiple poses, cropped subject, scenery, landscape, environment, environmental framing, ground plane, "
|
| 1769 |
+
"background props, drop shadow, text, watermark, blurry, soft focus, out of focus, low detail, smeared details, "
|
| 1770 |
+
"compression artifacts"
|
| 1771 |
+ camera_negative
|
| 1772 |
)
|
| 1773 |
if spec.composition == "seamless":
|
| 1774 |
+
return "visible seams, borders, frame, perspective mockup, text, watermark, blurry, soft focus, low detail" + camera_negative
|
| 1775 |
if spec.composition == "sprite_sheet":
|
| 1776 |
+
return "irregular grid, overlapping cells, labels, text, watermark, blurry, soft focus, low detail" + camera_negative
|
| 1777 |
+
return "text, labels, watermark, presentation mockup, blurry, soft focus, out of focus, low detail" + camera_negative
|
| 1778 |
|
| 1779 |
|
| 1780 |
def build_camera_control_image(spec: AssetSpec, width: int = 1024, height: int = 576) -> Image.Image:
|
|
|
|
| 1924 |
variation = f"Variation: {compact_prompt_words(spec.variation, 4)}. " if spec.variation else ""
|
| 1925 |
subject = (spec.group or spec.role).replace("_", " ")
|
| 1926 |
return (
|
| 1927 |
+
f"{camera} Single isolated {subject} subject. One complete centered body in one pose. "
|
| 1928 |
+
"Fill eighty percent of the frame with even margins. "
|
| 1929 |
+
"Crisp game-ready details. "
|
| 1930 |
"Plain uniform white field only; no environment, scenery, ground plane, or surrounding border. "
|
| 1931 |
f"{variation}{description}"
|
| 1932 |
)
|
| 1933 |
description = compact_prompt_words(spec.prompt, 26 if variation else 34)
|
| 1934 |
composition = {
|
| 1935 |
+
"icon": "Exactly one centered readable game icon with crisp details, uniform white field.",
|
| 1936 |
+
"animation_frame": "Exactly one isolated sharp animation frame subject at stable scale, uniform white field.",
|
| 1937 |
+
"full_frame": "One complete edge-to-edge game image with crisp readable details filling the canvas.",
|
| 1938 |
+
"seamless": "One sharp seamless edge-to-edge repeating game-art tile.",
|
| 1939 |
+
"sprite_sheet": "One crisp deliberately organized regular-grid sprite sheet.",
|
| 1940 |
+
"freeform": "One sharp user-defined game image following the requested composition exactly.",
|
| 1941 |
}[spec.composition]
|
| 1942 |
return f"{camera} {composition} {variation}{description}"
|
| 1943 |
|
|
|
|
| 2132 |
def polish_neural_cutout(image: Image.Image, spec: AssetSpec) -> bytes:
|
| 2133 |
"""Resize and normalize a neural alpha cutout without changing its generated RGB art."""
|
| 2134 |
contained = image.convert("RGBA")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2135 |
if spec.composition in {"single_subject", "icon", "animation_frame"}:
|
| 2136 |
+
# Crop the high-resolution model output first, then resize the subject
|
| 2137 |
+
# once. The previous thumbnail-then-normalize path resampled RGB twice
|
| 2138 |
+
# and visibly softened small game sprites.
|
| 2139 |
+
canvas = normalize_sprite_foreground(contained, spec)
|
| 2140 |
+
else:
|
| 2141 |
+
contained.thumbnail((spec.width, spec.height), Image.LANCZOS)
|
| 2142 |
+
canvas = Image.new("RGBA", (spec.width, spec.height), (0, 0, 0, 0))
|
| 2143 |
+
offset = ((spec.width - contained.width) // 2, (spec.height - contained.height) // 2)
|
| 2144 |
+
canvas.alpha_composite(contained, dest=offset)
|
| 2145 |
out = io.BytesIO()
|
| 2146 |
canvas.save(out, format="PNG")
|
| 2147 |
return out.getvalue()
|