[PR #41] [MERGED] fix(sprite): preserve partial transparency when placing frames #79

Closed
opened 2026-10-15 20:53:14 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/rehan-remade/universal-modder/pull/41
Author: @Overdusts
Created: 10/4/2026
Status: ✅ Merged
Merged: 10/5/2026
Merged by: @rehan-remade

Base: main ← Head: audit/fix-sprite-transparency


📝 Commits (1)

  • 4eea536 fix(sprite): preserve partial transparency when placing frames

📊 Changes

2 files changed (+17 additions, -3 deletions)

View changed files

📝 tests/test_um.py (+14 -0)
📝 um/sprite.py (+3 -3)

📄 Description

fix(sprite): preserve partial transparency when placing frames

fit, sheet packing, and squash animation frames currently use the source RGBA image as its own paste mask on a transparent canvas. This applies alpha twice and darkens RGB values: an unchanged-size (200, 100, 50, 128) pixel becomes (100, 50, 25, 64).

Paste the RGBA pixels directly in these three operations to preserve their original channels. Add 18 regression cases covering fit, sheet/slice round trips, and the first squash frame at six alpha levels, including fully opaque pixels.

Validation on Windows:

  • Original local environment, Python 3.13.3 / Pillow 11.2.1: python -m pytest -q tests reports 45 passed, 1 skipped (ffmpeg unavailable).
  • Clean source copies with Python 3.10.22 / Pillow 10.0.0 and Python 3.13.3 / Pillow 12.3.0: all 18 new regression cases pass. Running those exact tests against unchanged upstream produces 15 failures; the three fully opaque cases pass as expected.
  • Independent pixel-by-pixel checks cover 194 fit/sheet/squash cases per Pillow version, including trimming, all anchors, resizing, padding, varying frame sizes, fully transparent pixels, and clipping. PNG round trips preserve every result.
  • python -m um kb check --index: 20 notes passed.
  • python -m um publish check .: 246 files, no failures or warnings.
  • All nine CLI group help screens and git diff --check pass.

Broader verification with FFmpeg 7.1 exposes an existing test_compile_small_edl failure: xfade rejects frame-rate metadata 1/0 after setpts. Both unchanged upstream (27 passed, 1 failed) and this PR (45 passed, 1 failed) produce the same error in both isolated environments. This PR does not change video code. The failure was skipped in the original local run above.

No game or fal API calls are needed to reproduce the sprite defect. Game execution and Blender rendering were not tested.

Authored by @Overdusts with Codex (GPT-6).


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/rehan-remade/universal-modder/pull/41 **Author:** [@Overdusts](https://github.com/Overdusts) **Created:** 10/4/2026 **Status:** ✅ Merged **Merged:** 10/5/2026 **Merged by:** [@rehan-remade](https://github.com/rehan-remade) **Base:** `main` ← **Head:** `audit/fix-sprite-transparency` --- ### 📝 Commits (1) - [`4eea536`](https://github.com/rehan-remade/universal-modder/commit/4eea536c48b9a03c2d541c674487806d1c5eb568) fix(sprite): preserve partial transparency when placing frames ### 📊 Changes **2 files changed** (+17 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `tests/test_um.py` (+14 -0) 📝 `um/sprite.py` (+3 -3) </details> ### 📄 Description # fix(sprite): preserve partial transparency when placing frames `fit`, sheet packing, and squash animation frames currently use the source RGBA image as its own paste mask on a transparent canvas. This applies alpha twice and darkens RGB values: an unchanged-size `(200, 100, 50, 128)` pixel becomes `(100, 50, 25, 64)`. Paste the RGBA pixels directly in these three operations to preserve their original channels. Add 18 regression cases covering fit, sheet/slice round trips, and the first squash frame at six alpha levels, including fully opaque pixels. Validation on Windows: - Original local environment, Python 3.13.3 / Pillow 11.2.1: `python -m pytest -q tests` reports 45 passed, 1 skipped (ffmpeg unavailable). - Clean source copies with Python 3.10.22 / Pillow 10.0.0 and Python 3.13.3 / Pillow 12.3.0: all 18 new regression cases pass. Running those exact tests against unchanged upstream produces 15 failures; the three fully opaque cases pass as expected. - Independent pixel-by-pixel checks cover 194 fit/sheet/squash cases per Pillow version, including trimming, all anchors, resizing, padding, varying frame sizes, fully transparent pixels, and clipping. PNG round trips preserve every result. - `python -m um kb check --index`: 20 notes passed. - `python -m um publish check .`: 246 files, no failures or warnings. - All nine CLI group help screens and `git diff --check` pass. Broader verification with FFmpeg 7.1 exposes an existing `test_compile_small_edl` failure: `xfade` rejects frame-rate metadata `1/0` after `setpts`. Both unchanged upstream (27 passed, 1 failed) and this PR (45 passed, 1 failed) produce the same error in both isolated environments. This PR does not change video code. The failure was skipped in the original local run above. No game or fal API calls are needed to reproduce the sprite defect. Game execution and Blender rendering were not tested. Authored by @Overdusts with Codex (GPT-6). --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-15 20:53:14 +00:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rehan-remade/universal-modder#79
No description provided.