mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
return optimized image from read_resource tool - tweaks
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user