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

reload saved cropped image, onComplete returning incorrect crop, but percentCrop is correct. #596

Open
rafaellichen opened this issue Jul 26, 2024 · 0 comments

Comments

@rafaellichen
Copy link

rafaellichen commented Jul 26, 2024

Problem

pick a 430x430 image, crop with 100%, and save.
reload the image back by setting imgSrc, it triggers onComplete, returning:

crop = {"unit":"px","x":0,"y":0,"width":215,"height":215}
percentCrop = {"x":0,"y":0,"width":100,"height":100,"unit":"%"}

the returned crop is incorrect, and doesn't match the percentCrop.
in the crop editor area, the dashed box and the image are both correctly rendered (the dashed box is covering the entire image).

Visual Example

image

Expected

however, the crop inside onComplete is correctly returned when I load the same image from my computer (not the 100% cropped version that was saved to the database and retrieved later to load back).

i opened both cropped dataUrl and original file dataUrl in the browser, they look exactly the same visually.

my hack to fix this is to use the percenCrop with convertToPixelCrop inside onComplete callback.

<ReactCrop
    style={{ marginTop: 15 }}
    keepSelection
    crop={crop}
    onChange={(_, percentCrop) => {
        setCrop(percentCrop);
    }}
    onComplete={(crop, percentCrop) => {
        setCompletedCrop(
            convertToPixelCrop(
                percentCrop,
                imgRef.current.width,
                imgRef.current.height
            )
        );
    }}
    aspect={1}
    minWidth={80}
    minHeight={80}
>
    <img
        ref={imgRef}
        alt="Crop me"
        src={imgSrc}
        onLoad={onImageLoad}
    />
</ReactCrop>

code for saving cropped image

const image = imgRef.current;
const previewCanvas = previewCanvasRef.current;
if (!image || !previewCanvas || !completedCrop) {
    throw new Error("Crop canvas does not exist");
}

// This will size relative to the uploaded image
// size. If you want to size according to what they
// are looking at on screen, remove scaleX + scaleY
const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;

const offscreen = new OffscreenCanvas(
    completedCrop.width * scaleX,
    completedCrop.height * scaleY
);
const ctx = offscreen.getContext("2d");
if (!ctx) {
    throw new Error("No 2d context");
}

ctx.drawImage(
    previewCanvas,
    0,
    0,
    previewCanvas.width,
    previewCanvas.height,
    0,
    0,
    offscreen.width,
    offscreen.height
);

// You might want { type: "image/jpeg", quality: <0 to 1> } to
// reduce image size
const blob = await offscreen.convertToBlob({
    type: "image/jpeg",
    quality: 1,
});
const dataURL = await readFileAsDataURL(blob);
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

No branches or pull requests

1 participant