Skip to content

fix(crop-rotate): cover image edge with crop overlay when panned (#776)#838

Merged
hm21 merged 2 commits into
stablefrom
fix/776-crop-overlay-edge-seam
Jun 27, 2026
Merged

fix(crop-rotate): cover image edge with crop overlay when panned (#776)#838
hm21 merged 2 commits into
stablefrom
fix/776-crop-overlay-edge-seam

Conversation

@hm21

@hm21 hm21 commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Fixes #776

Problem

In the CropRotateEditor, when the image is panned so one of its edges floats inside the viewport (e.g. the image pushed to the bottom, bringing its top edge into view), a thin line of the image was visible at that edge even with cropOverlayOpacity: 1.

Root cause

The darkened crop overlay is painted on top of the image, and its outer rectangle was computed to be mathematically identical to the rendered image bounds (verified numerically — the edges match to within ~1e-13). Because the overlay's edge coincides exactly with the image's edge, anti-aliasing along that shared boundary leaves a ~1px partially-transparent seam (alpha ≈ 128 instead of 255), revealing the image underneath. At the viewport's own edges the seam is clipped away, which is why it only appeared on the panned-in edge.

Fix

Overscan the outer overlay rectangle by a small screen-space margin (1 logical px) so its edge lands just outside the image, on the surrounding background where the seam is invisible. The margin is divided by rotationScaleFactor to convert it from screen space into the painter's local space, keeping it visually constant across zoom levels — mirroring how the corner-thickness code already scales itself. The subtracted crop hole is untouched, so the crop area is unaffected.

Test

Added a regression test that rasterizes the overlay with a fractional pan offset and asserts the image's top-edge row is fully opaque. It fails before the fix (alpha = 128) and passes after (255).

hm21 added 2 commits June 27, 2026 15:59
The darkened crop overlay is painted on top of the image and its outer
rectangle was mathematically identical to the rendered image bounds. When
the image is panned so an edge floats inside the viewport (e.g. pushed to
the bottom), anti-aliasing along that shared edge left a ~1px
partially-transparent seam that revealed a thin line of the image.

Overscan the outer overlay rectangle by a small screen-space margin so its
edge lands just outside the image, moving the seam onto the surrounding
background where it is invisible. The margin is converted into the
painter's local space via rotationScaleFactor so it stays visually
constant across zoom levels.
@hm21 hm21 merged commit e84aecc into stable Jun 27, 2026
1 check passed
@hm21 hm21 deleted the fix/776-crop-overlay-edge-seam branch June 27, 2026 14:03
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.

[Bug]: In the cCropRotateEditor, when the image is at the bottom, the top edge of the image is not covered by crop OverlayOpacity

1 participant