Skip to content

Fix hatch-pet chroma-key halo and webp transparent-RGB loss#400

Open
shmulc8 wants to merge 1 commit into
openai:mainfrom
shmulc8:fix-hatch-pet-magenta-halo
Open

Fix hatch-pet chroma-key halo and webp transparent-RGB loss#400
shmulc8 wants to merge 1 commit into
openai:mainfrom
shmulc8:fix-hatch-pet-magenta-halo

Conversation

@shmulc8
Copy link
Copy Markdown

@shmulc8 shmulc8 commented May 7, 2026

Summary

Two related fixes in the curated hatch-pet skill that together cause a magenta (or other chroma-key) tinted halo around extracted pet sprites in the final spritesheet.

Root cause

  1. scripts/extract_strip_frames.pyremove_chroma_background only zeros alpha on chroma-keyed pixels and keeps the original RGB:

    pixels[x, y] = (red, green, blue, 0)

    The subsequent fit_to_cell resize uses Image.Resampling.LANCZOS, which interpolates RGB and alpha independently. Transparent pixels still carrying chroma RGB then leak color into neighboring partially-opaque edge pixels during downscaling, producing a faint tinted halo (e.g. (127, 0, 127, 2), (85, 0, 85, 3) for a magenta key) around every sprite.

  2. scripts/compose_atlas.pysave_outputs writes the WebP atlas with lossless=True but without exact=True. Without exact=True, libwebp is free to overwrite RGB on fully-transparent pixels during compression for better packing. Combined with Update readme with initial text; add gitignore #1, this can also re-introduce non-zero RGB on alpha=0 pixels in the published atlas, which any renderer that ignores the alpha channel will display as solid chroma-key color.

Fixes

  1. In remove_chroma_background, set chroma-keyed pixels to (0, 0, 0, 0) so the resize cannot pull chroma color into sprite edges.
  2. In save_outputs, pass exact=True alongside lossless=True so transparent-pixel RGB is preserved as-written.

Both changes are tiny and surgical — no behavior change for non-chroma-key pixels.

Test plan

  • Run extract_strip_frames.py on a strip with a magenta (#FF00FF) chroma-key background and verify post-extraction frames have no (R≈B, G≈0, alpha>0) pixels along sprite edges.
  • Compose an atlas via compose_atlas.py --webp-output ... and verify with PIL that there are no chroma-family RGB values on alpha==0 pixels in the saved WebP.
  • Visually check the final spritesheet in a renderer that ignores alpha (e.g. some sprite preview tools) — there should be no solid chroma-key fill where transparency is expected.

Two related issues caused a magenta/chroma-key tinted halo around
extracted pet sprites:

1. extract_strip_frames.remove_chroma_background only zeroed alpha on
   chroma-keyed pixels, leaving the original chroma RGB intact. The
   subsequent LANCZOS resize in fit_to_cell blends RGB and alpha
   independently, so transparent chroma-RGB neighbors leak color into
   sprite edges and create a visible tinted halo. Zero RGB together
   with alpha so the resize cannot pull chroma color into edges.

2. compose_atlas.save_outputs writes the WebP with lossless=True but
   without exact=True, which lets libwebp rewrite RGB on transparent
   pixels during compression. Pair lossless with exact so transparent-
   pixel RGB is preserved.
@shmulc8 shmulc8 requested a review from a team May 7, 2026 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants