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:
2026-04-22 09:50:08 +03:00
parent 59565c9b8a
commit 197dcadfee
5 changed files with 149 additions and 9 deletions

View File

@@ -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)