Skip to content

fix: hash transparent images as they look on a white background - #92

Merged
Toldry merged 3 commits into
masterfrom
fix/flatten-transparent-images
Oct 16, 2026
Merged

Toldry merged 3 commits into
masterfrom
fix/flatten-transparent-images

Conversation

@Toldry

@Toldry Toldry commented Oct 16, 2026

Copy link
Copy Markdown
Owner

Requested by Querent · project thread

Before: when the image duplicate scan met a palette PNG with partial transparency, Pillow logged UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images in production. More importantly, every transparent image was hashed by the hidden colour stored behind its see-through pixels (grayscale conversion ignores alpha), so two visually identical copies saved by different programs could get completely different hashes and not match.

After: transparent images are laid over a white background before hashing, so the scan compares what a viewer sees, and the warning no longer appears. Opaque images are hashed exactly as before.

How: a new flatten_transparency() in duplicate_detector.py alpha-composites any image with has_transparency_data onto white (via RGBA, the conversion Pillow's warning asks for) before both the whole-image and region dhashes. Hashes are only cached in memory, not stored in the database, so nothing needs migrating. Two unit tests: a transparent palette PNG with a black hidden background, one with a white hidden background, and a flattened JPEG all match, with warnings turned into errors; and opaque images pass through untouched. The first test fails on master. Full unit suite: 1699 passed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CAPbY36A2C1ujRpj8CZWgi


Generated by Claude Code

Grayscale conversion ignores alpha, so transparent pixels were hashed by
whatever colour was stored behind them, and palette PNGs with byte
transparency made Pillow emit a UserWarning on every scan.

Co-Authored-By: Toldry <toldry@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CAPbY36A2C1ujRpj8CZWgi
@Toldry Toldry self-assigned this Oct 16, 2026
claude and others added 2 commits October 16, 2026 17:34
Co-Authored-By: Toldry <toldry@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EGsDrajpL6puoVuiCcZvoR
Co-Authored-By: Toldry <toldry@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EGsDrajpL6puoVuiCcZvoR
@Toldry
Toldry marked this pull request as ready for review October 16, 2026 17:36
@Toldry
Toldry merged commit 33361b1 into master Oct 16, 2026
4 checks passed
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