Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUGFIX: fix bug with pixelSnapping on certain aspectRatios and image dimensions #3578

Open
wants to merge 1 commit into
base: 8.2
Choose a base branch
from

Conversation

patricekaufmann
Copy link
Contributor

@patricekaufmann patricekaufmann commented Jul 11, 2023

With 8.2 the pixelSnapping feature got introduced #3065. We started using it in all our installations and I noticed a rare bug happening with specific combinations of image sizes and aspect ratio.

Since only cropArea.width is used for calculating the dimensions, it might happen that the resulting naturalCropHeight was bigger than the image itself, leading to errors when trying to save the image. I think it happened due to rounding in react-crop component.

The solution is made this way to keep ensuring correct aspect ratio values, incrementally subtracting the normalized aspect ratio values until the area is valid.

@github-actions github-actions bot added Bug Label to mark the change as bugfix 8.2 labels Jul 11, 2023
@crydotsnake
Copy link
Member

How can i reproduce the described issue?

@patricekaufmann
Copy link
Contributor Author

First you would need an ImageInterace property with the following editorOptions:

editorOptions:
  crop:
    aspectRatio:
     pixelSnapping: TRUE

The issue appears when editing the image inside the inspector, so that would need to be configured aswell.
Since this issue only appears on certain image dimensions and aspect ratios, I attach the following sample image which leads to an error in 2:3 aspect ratio: Sample Gradient JPG

The issue now occurs when moving the croparea on the ImageCropper without ever adjusting its size as demonstrated in the following video. It does not occur when not moving the area or resizing the area in addition to moving it, even dragging it to its maximum size.

G5FTdrdHg5.mp4

To refer to the actual error message: the crop area has an y value of -1 because the area is larger than the actual image.

Is that of any use to you so that you are able to review / test it properly? Otherwise let me know if there is anything else I can prepare.

Copy link
Contributor

@grebaldi grebaldi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @patricekaufmann,

thanks a lot for your fix :) I was able to verify that it works as described.

👍

@mhsdesign
Copy link
Member

mhsdesign commented Jul 12, 2023

Hmm with your image i can reproduce the bug. And also when creating an image with the same dimensions.

HugeImage

same ratio as yours:
fwefwef

different ratio:
ewfwef

also the editor behaves weird when trying to crop the 341 one ... (edit: its not actually 340,9 only my photo program told me that this were the dimensions after downscaling)

image

(when pixel Snapping =1 ) there is a little gap below:

image


if you like we can have a call about this so we can move faster forward ^^

@patricekaufmann
Copy link
Contributor Author

if you like we can have a call about this so we can move faster forward ^^

I reached out to @mhsdesign and we decided upon calling about this sometime next week. Until the problem is resolved, we will disable the snapping.

Comment on lines +165 to +169
while (naturalCropHeight > imageHeight) {
// can't crop area larger than image itself, so keep subtracting normalized aspect ratio values until area is valid
naturalCropHeight -= normalizedAspectRatioHeight;
naturalCropWidth -= normalizedAspectRatioWidth;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should be sure that this while loop never causes the ui to freeze (eg. are negative values at any time possible? - if so we need to guard against this ...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assumption being made in the following statements is that imageHeight will be positive or 0.

The loop then terminates when one of the following conditions is met:

normalizedAspectRatioHeight > 0 or naturalCropHeight < 0

If we actually substitute the variables in naturalCropHeight variable declaration and ignore the floor function since it wouldn't change the sign , you eventually get a minimized form like

let naturalCropHeightWithoutFloor = cropArea.width * imageWidth * (currentAspectRatioStrategy.height /( 100 * currentAspectRatioStrategy.width)) (see Wolframalpha)

From that we can see that if either passed variable in crop configuration is negative, naturalCropHeight will be smaller than zero and the loop will never start.

If both configuration dimension variables are positive the aspectRatioGcd will be positive and therefore normalizedAspectRatioHeight will be positive, hence the loop with exit eventually.

If both are negative, naturalCropHeight will be greater than 0 and normalizedAspectRatioHeight will be smaller than 0. In that case the loop will not exit. Math.abs() on aspectRatioGcd would cover that edge case (I mean who passes negative values in the aspectRatio configuration ?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
8.2 Bug Label to mark the change as bugfix next-patch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants