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:
+15
-8
@@ -81,13 +81,14 @@ def extract(input_pdf):
|
|||||||
|
|
||||||
print(f"Extracted {len(pages)} pages to {temp_dir}/")
|
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.
|
"""Remove white space from around the image.
|
||||||
|
|
||||||
Handles both RGB and RGBA images, treating transparent pixels as white.
|
Handles both RGB and RGBA images, treating transparent pixels as white.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
image_path: Path to the image file
|
image_path: Path to the image file
|
||||||
|
is_final: Whether this is the final operation on the image
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if successful, False otherwise
|
bool: True if successful, False otherwise
|
||||||
@@ -124,8 +125,8 @@ def trim_whitespace(image_path: str) -> bool:
|
|||||||
# Crop the original image (preserving transparency)
|
# Crop the original image (preserving transparency)
|
||||||
cropped = image.crop((x1, y1, x2, y2))
|
cropped = image.crop((x1, y1, x2, y2))
|
||||||
|
|
||||||
# Save the cropped image
|
# Save the cropped image, optimizing only if this is the final operation
|
||||||
cropped.save(image_path, "PNG", optimize=False)
|
cropped.save(image_path, "PNG", optimize=is_final)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -206,11 +207,15 @@ def deskew():
|
|||||||
else:
|
else:
|
||||||
print(" No line segments detected")
|
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.
|
"""Convert image to 1-bit monochrome.
|
||||||
|
|
||||||
Handles RGBA images by converting transparent pixels to white before thresholding.
|
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:
|
Returns:
|
||||||
bool: True if successful, False otherwise
|
bool: True if successful, False otherwise
|
||||||
"""
|
"""
|
||||||
@@ -243,8 +248,8 @@ def convert_to_monochrome(image_path: str) -> bool:
|
|||||||
# Convert to 1-bit using threshold
|
# Convert to 1-bit using threshold
|
||||||
image = image.point(lambda x: 255 if x > settings.MONOCHROME_THRESHOLD else 0, '1')
|
image = image.point(lambda x: 255 if x > settings.MONOCHROME_THRESHOLD else 0, '1')
|
||||||
|
|
||||||
# Save the monochrome image
|
# Save the monochrome image, optimizing only if this is the final operation
|
||||||
image.save(image_path, "PNG", optimize=False)
|
image.save(image_path, "PNG", optimize=is_final)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -312,7 +317,8 @@ def optimize(level):
|
|||||||
print("\nTrimming whitespace from images...")
|
print("\nTrimming whitespace from images...")
|
||||||
for i, file_path in enumerate(temp_files, 1):
|
for i, file_path in enumerate(temp_files, 1):
|
||||||
print(f"[{i}/{total_files}] Processing {os.path.basename(file_path)}...", end='', flush=True)
|
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
|
successful['trim'] += 1
|
||||||
print(" ")
|
print(" ")
|
||||||
else:
|
else:
|
||||||
@@ -323,7 +329,8 @@ def optimize(level):
|
|||||||
print("\nConverting to monochrome...")
|
print("\nConverting to monochrome...")
|
||||||
for i, file_path in enumerate(temp_files, 1):
|
for i, file_path in enumerate(temp_files, 1):
|
||||||
print(f"[{i}/{total_files}] Converting {os.path.basename(file_path)}...", end='', flush=True)
|
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
|
successful['monochrome'] += 1
|
||||||
print(" ")
|
print(" ")
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user