perf: optimize PNG compression only on final operations

- Add is_final parameter to trim_whitespace and convert_to_monochrome
- Only optimize PNGs on the final operation of each level
- Remove optimization from extract command
- Level 1: optimize in trim_whitespace
- Level 2: optimize in convert_to_monochrome
- Level 3: defer to optipng
This commit is contained in:
Esa Kataja
2024-12-03 22:23:54 +02:00
parent 75dc1c3e2c
commit a979712c8c
+15 -8
View File
@@ -81,13 +81,14 @@ def extract(input_pdf):
print(f"Extracted {len(pages)} pages to {temp_dir}/")
def trim_whitespace(image_path: str) -> bool:
def trim_whitespace(image_path: str, is_final: bool = False) -> bool:
"""Remove white space from around the image.
Handles both RGB and RGBA images, treating transparent pixels as white.
Args:
image_path: Path to the image file
is_final: Whether this is the final operation on the image
Returns:
bool: True if successful, False otherwise
@@ -124,8 +125,8 @@ def trim_whitespace(image_path: str) -> bool:
# Crop the original image (preserving transparency)
cropped = image.crop((x1, y1, x2, y2))
# Save the cropped image
cropped.save(image_path, "PNG", optimize=False)
# Save the cropped image, optimizing only if this is the final operation
cropped.save(image_path, "PNG", optimize=is_final)
return True
except Exception as e:
@@ -206,11 +207,15 @@ def deskew():
else:
print(" No line segments detected")
def convert_to_monochrome(image_path: str) -> bool:
def convert_to_monochrome(image_path: str, is_final: bool = False) -> bool:
"""Convert image to 1-bit monochrome.
Handles RGBA images by converting transparent pixels to white before thresholding.
Args:
image_path: Path to the image file
is_final: Whether this is the final operation on the image
Returns:
bool: True if successful, False otherwise
"""
@@ -243,8 +248,8 @@ def convert_to_monochrome(image_path: str) -> bool:
# Convert to 1-bit using threshold
image = image.point(lambda x: 255 if x > settings.MONOCHROME_THRESHOLD else 0, '1')
# Save the monochrome image
image.save(image_path, "PNG", optimize=False)
# Save the monochrome image, optimizing only if this is the final operation
image.save(image_path, "PNG", optimize=is_final)
return True
except Exception as e:
@@ -312,7 +317,8 @@ def optimize(level):
print("\nTrimming whitespace from images...")
for i, file_path in enumerate(temp_files, 1):
print(f"[{i}/{total_files}] Processing {os.path.basename(file_path)}...", end='', flush=True)
if trim_whitespace(file_path):
# Only optimize if this is the final step (level 1)
if trim_whitespace(file_path, is_final=(opt_level == OptimizationLevel.TRIM)):
successful['trim'] += 1
print(" ")
else:
@@ -323,7 +329,8 @@ def optimize(level):
print("\nConverting to monochrome...")
for i, file_path in enumerate(temp_files, 1):
print(f"[{i}/{total_files}] Converting {os.path.basename(file_path)}...", end='', flush=True)
if convert_to_monochrome(file_path):
# Only optimize if this is the final step (level 2)
if convert_to_monochrome(file_path, is_final=(opt_level == OptimizationLevel.MONOCHROME)):
successful['monochrome'] += 1
print(" ")
else: