fix: CRITICAL - remove double rotation (frontend + backend)
Root cause: Image was being rotated TWICE: 1. Frontend rotated it in the modal and sent processed blob 2. Backend rotated it AGAIN based on rotation_degrees This double rotation made the image appear unrotated or distorted. Solution: Remove frontend image processing entirely. - Modal now sends ONLY the rotation value - No imageBlob from modal (uses original) - Backend receives original image + rotation value - Backend applies rotation ONCE Now image is rotated correctly by backend without duplication. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -96,9 +96,12 @@ export default function AIOnboarding({ onCancel, onComplete, categories, invento
|
||||
// CRITICAL: Update state AND processed blob BEFORE calling hook
|
||||
setExtractedItems(updatedItems);
|
||||
|
||||
// DON'T replace image blob - modal no longer processes image
|
||||
// Backend will apply rotation to original image
|
||||
if (adjustments.imageBlob) {
|
||||
console.log('[Update] Setting extractedImageBlob to processed blob:', adjustments.imageBlob.size, 'bytes');
|
||||
setExtractedImageBlob(adjustments.imageBlob);
|
||||
console.log('[Update] Processed blob received but NOT using (backend will process)');
|
||||
} else {
|
||||
console.log('[Update] No imageBlob - using original, backend will apply rotation');
|
||||
}
|
||||
|
||||
// CRITICAL: Call hook with UPDATED item, not old one
|
||||
|
||||
@@ -130,57 +130,21 @@ export function ImageAdjustmentModal({ imageUrl, onConfirm, onCancel }: ImageAdj
|
||||
console.log('[User] Rotation:', rotation, '°');
|
||||
console.log('[User] Use image flag:', useImage);
|
||||
|
||||
// Process image: apply rotation ONLY (no crop)
|
||||
const processCanvas = document.createElement('canvas');
|
||||
const ctx = processCanvas.getContext('2d');
|
||||
if (!ctx) {
|
||||
console.log('[ERROR] Could not get canvas context');
|
||||
return;
|
||||
}
|
||||
|
||||
// DON'T process image in frontend - let backend handle rotation
|
||||
// Just send the rotation value, backend will apply it once
|
||||
const { width, height } = imageDimensions;
|
||||
|
||||
// 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);
|
||||
console.log('[Decision] Sending rotation to backend for processing');
|
||||
console.log('[Decision] NOT processing image in frontend (avoid double rotation)');
|
||||
console.log('=== END DEBUG ===');
|
||||
|
||||
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 of canvas
|
||||
ctx.save();
|
||||
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');
|
||||
|
||||
// Convert to blob
|
||||
processCanvas.toBlob((blob) => {
|
||||
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 new canvas bounds and rotation
|
||||
onConfirm({
|
||||
rotation,
|
||||
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: newWidth, height: newHeight } });
|
||||
}
|
||||
}, 'image/jpeg', 0.95);
|
||||
// Return rotation value ONLY - no imageBlob
|
||||
// Backend will apply rotation to original image
|
||||
onConfirm({
|
||||
rotation,
|
||||
cropBounds: { x: 0, y: 0, width, height }
|
||||
// NO imageBlob - use original from extractedImageBlob
|
||||
});
|
||||
};
|
||||
|
||||
const handleWheel = (e: React.WheelEvent<HTMLCanvasElement>) => {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user