fix: apply crop bounds before EXIF rotation to match AI analysis
Gemini analyzes raw image and returns crop_bounds for that coordinate space. Previous code applied EXIF rotation first, changing image dimensions, then used crop_bounds on the rotated image (coordinate mismatch). Now: crop on raw image (matches AI) → then apply EXIF + manual rotation. This ensures cropped region contains the actual item, not background.
This commit is contained in:
@@ -78,25 +78,22 @@ class ImageProcessor:
|
||||
'thumbnail_bytes': None,
|
||||
}
|
||||
|
||||
# Open image with PIL
|
||||
# Open image with PIL (without applying EXIF yet, so crop_bounds match AI analysis)
|
||||
image = Image.open(io.BytesIO(file_bytes))
|
||||
original_size = image.size
|
||||
self.logger.info(f"[PROCESS] Input: {len(file_bytes)} bytes, size={original_size}, crop_bounds={crop_bounds}, rotation={rotation_degrees}°")
|
||||
|
||||
# Extract and apply EXIF orientation
|
||||
# Extract EXIF orientation (but don't apply yet)
|
||||
exif_orientation = self._extract_exif_orientation(image)
|
||||
if exif_orientation and exif_orientation > 1:
|
||||
image = self._rotate_by_orientation(image, exif_orientation)
|
||||
self.logger.info(f"Applied EXIF rotation: {exif_orientation}")
|
||||
|
||||
# Smart cropping
|
||||
# Smart cropping (on raw, un-rotated image so crop_bounds match AI analysis)
|
||||
cropped_image = image
|
||||
crop_size = None
|
||||
text_angle = None
|
||||
crop_method = 'none'
|
||||
|
||||
if crop_bounds:
|
||||
# Manual crop bounds provided
|
||||
# Manual crop bounds provided (from AI, based on raw image)
|
||||
crop_rect = (
|
||||
crop_bounds['x'],
|
||||
crop_bounds['y'],
|
||||
@@ -109,7 +106,7 @@ class ImageProcessor:
|
||||
crop_method = 'manual'
|
||||
self.logger.info(f"[CROP] Result size: {crop_size}, pixels={crop_size[0]*crop_size[1]}")
|
||||
else:
|
||||
# Try OpenCV smart crop
|
||||
# Try OpenCV smart crop on raw image
|
||||
self.logger.info("[CROP] Attempting OpenCV smart crop...")
|
||||
try:
|
||||
crop_result = self._smart_crop_opencv(image)
|
||||
@@ -140,6 +137,11 @@ class ImageProcessor:
|
||||
)
|
||||
crop_method = 'pillow'
|
||||
|
||||
# Now apply EXIF orientation to the cropped image
|
||||
if exif_orientation and exif_orientation > 1:
|
||||
cropped_image = self._rotate_by_orientation(cropped_image, exif_orientation)
|
||||
self.logger.info(f"Applied EXIF rotation: {exif_orientation}")
|
||||
|
||||
# Apply manual rotation if provided
|
||||
if abs(rotation_degrees) > 0.5:
|
||||
cropped_image = cropped_image.rotate(-rotation_degrees, expand=True)
|
||||
|
||||
Reference in New Issue
Block a user