return optimized image from read_resource tool - tweaks

This commit is contained in:
phernandez
2025-02-23 16:54:07 -06:00
parent 959b278687
commit ab36e7e560
+45 -23
View File
@@ -12,14 +12,18 @@ from PIL import Image as PILImage
def resize_image(img, max_size):
"""Resize image maintaining aspect ratio"""
original_dimensions = {"width": img.width, "height": img.height}
if img.width > max_size or img.height > max_size:
ratio = min(max_size / img.width, max_size / img.height)
new_size = (int(img.width * ratio), int(img.height * ratio))
logger.debug("Resizing image", original={
"width": img.width,
"height": img.height
}, target=new_size)
logger.debug("Resizing image",
original=original_dimensions,
target=new_size,
ratio=ratio)
return img.resize(new_size, PILImage.Resampling.LANCZOS)
logger.debug("No resize needed", dimensions=original_dimensions)
return img
def optimize_image(img, max_output_bytes=500000): # 500KB limit
@@ -29,16 +33,22 @@ def optimize_image(img, max_output_bytes=500000): # 500KB limit
mode=img.mode,
max_bytes=max_output_bytes)
# Convert to RGB if needed
if img.mode in ('RGBA', 'LA') or (img.mode == 'P' and 'transparency' in img.info):
img = img.convert('RGB')
logger.debug("Converted image to RGB")
# Start with higher quality for better color preservation
quality = 60
quality = 30
size = 400
# Make initial size relative to input dimensions
initial_size = min(800, max(img.width, img.height))
size = initial_size
original_mode = img.mode
if img.mode in ('RGBA', 'LA') or (img.mode == 'P' and 'transparency' in img.info):
# Keep original mode info for logging
img = img.convert('RGB')
logger.debug("Converted color mode",
from_mode=original_mode,
to_mode='RGB')
while True:
# Try current settings
buf = io.BytesIO()
resized = resize_image(img, size)
@@ -49,23 +59,35 @@ def optimize_image(img, max_output_bytes=500000): # 500KB limit
subsampling='4:2:0')
output_size = buf.getbuffer().nbytes
logger.debug("Optimization attempt", quality=quality, size=size, output_bytes=output_size)
logger.debug("Optimization attempt",
quality=quality,
size=size,
output_bytes=output_size,
target_bytes=max_output_bytes)
if output_size < max_output_bytes:
compression_ratio = output_size / max_output_bytes
logger.info("Image optimization complete",
final_size=output_size,
quality=quality,
dimensions={"width": resized.width, "height": resized.height})
final_size=output_size,
quality=quality,
dimensions={"width": resized.width, "height": resized.height},
compression_ratio=compression_ratio)
return buf.getvalue()
# Try lower quality first
if quality > 10:
quality -= 10
logger.debug("Reducing quality", new_quality=quality)
# Then reduce size if quality is already minimum
elif size > 200:
size -= 50
logger.debug("Reducing size", new_size=size)
# More gradual quality reduction for better color preservation
if quality > 30:
quality_step = 5 if quality > 50 else 10
quality -= quality_step
logger.debug("Reducing quality",
new_quality=quality,
step=quality_step)
# Smaller size reduction steps
elif size > 300:
size_step = 25 if size > 600 else 50
size -= size_step
logger.debug("Reducing size",
new_size=size,
step=size_step)
else:
logger.warning("Reached minimum optimization parameters",
final_size=output_size,