Repository navigation
Show transparent images frameless, like stickers - #27
Merged
Merged
Conversation
A mostly see-through PNG/WebP/GIF/AVIF is nearly always meant as a sticker, and drawing it on a bordered card puts back the box it was cut out of. Check the pixels of the thumbnail already on screen (over IPC, so the canvas isn't tainted) and drop the frame, background and cropping for cut-outs. Size is unchanged so the timeline doesn't shift; answers are remembered across launches. get_media_bytes takes an optional size so the check hits the same cache entry as the <img>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Images that are mostly transparent now render the way stickers do: no card border, no background, no rounded frame, and
object-fit: containinstead ofcover. Clicking still opens the lightbox.Why
A transparent PNG pasted into a room is nearly always meant as a sticker (a character, a reaction, something cut out of its background). The card frame puts back the box it was cut out of.
How
src/lib/cutout.ts(new): forimage/png|apng|webp|gif|avifonly, fetches the thumbnail the timeline already shows, draws it at 48×48 and counts pixels with alpha < 128. If 4% or more are see-through, it's a cut-out. Answers are cached per mxc in memory and in localStorage (capped at 500), so there's no frame flash on later launches. Failed checks aren't persisted.<img>: an image fromuwum://is cross-origin, so drawing it taints the canvas. Rather than adding CORS headers to the private media protocol, the bytes come overget_media_bytes.get_media_bytesnow takes optionalwidth/heightso the check requests the same thumbnail as the<img>and hits the SDK media cache. Existing callers (video/audio) pass neither and behave as before.thumbnailSize()is factored out ofmediaUrlinipc.tsso both compute the same size.ImageBody: cut-outs keep their picture-sized box, so detection doesn't shift the timeline.Reviewer notes
cargo check, and all 159 tests pass, 5 of them new forisCutout.🤖 Generated with Claude Code