Open
Description
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

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);
Metadata
Metadata
Assignees
Labels
No labels