fix: CRITICAL - prevent image clipping when rotating
When rotating images, the rotated corners extend beyond the original canvas bounds, causing the image to be clipped and appear skewed. Fixed by: 1. Calculate canvas size needed to fit rotated image 2. Use formula: newSize = sqrt((w*cos)^2 + (h*sin)^2) 3. Center image and rotate around center of new canvas 4. Update cropBounds to new canvas dimensions Now when user rotates an image, the full rotated result is saved without any clipping or skewing. The saved image dimensions will be larger than the original to accommodate the rotation. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -138,22 +138,27 @@ export function ImageAdjustmentModal({ imageUrl, onConfirm, onCancel }: ImageAdj
|
||||
return;
|
||||
}
|
||||
|
||||
// Use full image dimensions (no cropping)
|
||||
const { width, height } = imageDimensions;
|
||||
processCanvas.width = width;
|
||||
processCanvas.height = height;
|
||||
|
||||
console.log('[Processing] Canvas dimensions:', width, 'x', height);
|
||||
// Calculate canvas size needed to fit rotated image (prevent clipping)
|
||||
const radians = (rotation * Math.PI) / 180;
|
||||
const cos = Math.abs(Math.cos(radians));
|
||||
const sin = Math.abs(Math.sin(radians));
|
||||
const newWidth = Math.ceil(width * cos + height * sin);
|
||||
const newHeight = Math.ceil(width * sin + height * cos);
|
||||
|
||||
processCanvas.width = newWidth;
|
||||
processCanvas.height = newHeight;
|
||||
|
||||
console.log('[Processing] Original dimensions:', width, 'x', height);
|
||||
console.log('[Processing] Canvas size for rotation:', newWidth, 'x', newHeight);
|
||||
console.log('[Processing] Applying rotation:', rotation, '°');
|
||||
|
||||
// Apply rotation around center
|
||||
// Apply rotation around center of canvas
|
||||
ctx.save();
|
||||
ctx.translate(width / 2, height / 2);
|
||||
ctx.rotate((rotation * Math.PI) / 180);
|
||||
ctx.translate(-width / 2, -height / 2);
|
||||
|
||||
console.log('[Processing] Drawing image with rotation applied');
|
||||
ctx.drawImage(imageRef.current, 0, 0);
|
||||
ctx.translate(newWidth / 2, newHeight / 2);
|
||||
ctx.rotate(radians);
|
||||
ctx.drawImage(imageRef.current, -width / 2, -height / 2);
|
||||
ctx.restore();
|
||||
|
||||
console.log('[Processing] Canvas draw complete');
|
||||
@@ -163,16 +168,17 @@ export function ImageAdjustmentModal({ imageUrl, onConfirm, onCancel }: ImageAdj
|
||||
if (blob) {
|
||||
console.log('[Result] Processed image blob size:', blob.size, 'bytes');
|
||||
console.log('[Result] Blob type:', blob.type);
|
||||
console.log('[Result] Final canvas size:', newWidth, 'x', newHeight);
|
||||
console.log('=== END DEBUG ===');
|
||||
// Return with full image bounds (no crop) and rotation
|
||||
// Return with new canvas bounds and rotation
|
||||
onConfirm({
|
||||
rotation,
|
||||
cropBounds: { x: 0, y: 0, width, height },
|
||||
cropBounds: { x: 0, y: 0, width: newWidth, height: newHeight },
|
||||
imageBlob: blob
|
||||
});
|
||||
} else {
|
||||
console.log('[ERROR] Failed to convert canvas to blob');
|
||||
onConfirm({ rotation, cropBounds: { x: 0, y: 0, width, height } });
|
||||
onConfirm({ rotation, cropBounds: { x: 0, y: 0, width: newWidth, height: newHeight } });
|
||||
}
|
||||
}, 'image/jpeg', 0.95);
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user