diff --git a/scripts/local/resize_images.py b/scripts/local/resize_images.py index 9211635f..dede0c50 100644 --- a/scripts/local/resize_images.py +++ b/scripts/local/resize_images.py @@ -1,11 +1,46 @@ -# --replace flag (false by default, overwrites if same ext, deletes if diff ext) -# Print number of files found -# Confirmation before overwrite -# Input directory -# Output directory - -# Skip corrupt images and print their path in output -# --trigger-size [0] -# --max-width -# --max-height -# --outputExtension () +import os +from utils.bulk_ops_common import ( + get_local_argparser, + run_argparser, + walk_and_extract_files, + resize_image, +) + + +def resize_images(input_dir, output_dir, max_width, max_height, trigger_size): + """ + Resize images in the input directory and save them in the output directory. + + :param input_dir: Directory containing images to be resized. + :param output_dir: Directory to save resized images. + :param max_width: Maximum width for resizing. + :param max_height: Maximum height for resizing. + :param trigger_size: Minimum file size in bytes to trigger resizing. + """ + # Extract image files from the input directory + file_extensions = ["jpg", "jpeg", "png", "tiff"] + files = walk_and_extract_files(input_dir, file_extensions) + + # Ensure the output directory exists + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + # Resize each image and save it to the output directory + for file_path in files: + output_file_path = os.path.join(output_dir, os.path.basename(file_path)) + resize_image(file_path, output_file_path, max_width, max_height, trigger_size) + + +if __name__ == "__main__": + # Set up argument parser and parse arguments + argparser = get_local_argparser() + args = run_argparser(argparser) + + # Call the resize_images function with parsed arguments + resize_images( + input_dir=args["input"], + output_dir=args["output"], + max_width=args["max_width"], + max_height=args["max_height"], + trigger_size=args["trigger_size"], + ) diff --git a/scripts/local/utils/bulk_ops_common.py b/scripts/local/utils/bulk_ops_common.py index 071a7137..d99d02c5 100644 --- a/scripts/local/utils/bulk_ops_common.py +++ b/scripts/local/utils/bulk_ops_common.py @@ -3,6 +3,8 @@ import glob import operator import os +from PIL import Image, UnidentifiedImageError +from src.utils.file import PathUtils from src.utils.file import PathUtils @@ -119,3 +121,38 @@ def run_argparser(argparser): raise Exception(f"\nError: Unknown arguments: {unknown}") return args + + +def resize_image( + input_path, output_path, max_width=None, max_height=None, trigger_size=0 +): + """ + Resize an image based on given width, height, and trigger size. + + :param input_path: Path to the input image. + :param output_path: Path to save the resized image. + :param max_width: Maximum width for resizing. + :param max_height: Maximum height for resizing. + :param trigger_size: Minimum file size in bytes to trigger resizing. + """ + try: + if os.path.getsize(input_path) > trigger_size: + with Image.open(input_path) as img: + width, height = img.size + + # Resize based on max width or height while keeping the aspect ratio + if max_width and width > max_width: + new_height = int((max_width / width) * height) + img = img.resize((max_width, new_height), Image.ANTIALIAS) + + if max_height and height > max_height: + new_width = int((max_height / height) * width) + img = img.resize((new_width, max_height), Image.ANTIALIAS) + + # Save the resized image + img.save(output_path) + print(f"Resized image saved at: {output_path}") + except UnidentifiedImageError: + print(f"Skipping corrupt image: {input_path}") + except Exception as e: + print(f"Error resizing image {input_path}: {e}") diff --git a/scripts/run_all_tests_and_coverage.sh b/scripts/run_all_tests_and_coverage.sh index 788e6744..f00db614 100755 --- a/scripts/run_all_tests_and_coverage.sh +++ b/scripts/run_all_tests_and_coverage.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env sh # Note: we need this run in a file because currently the 'language: system' # type in pre-commit-config doesn't seem to support multiple commands (even on using &&) coverage run --source src -m pytest -rfpsxEX --disable-warnings --verbose --durations=3 diff --git a/scripts/run_python_hook.sh b/scripts/run_python_hook.sh index beedd560..d19ee0d0 100755 --- a/scripts/run_python_hook.sh +++ b/scripts/run_python_hook.sh @@ -1,3 +1,3 @@ -#!/bin/sh +#!/usr/bin/env sh echo "PYTHONPATH=$PWD:$PYTHONPATH python3 $@" PYTHONPATH="$PWD:$PYTHONPATH" python3 "$@" diff --git a/scripts/run_single_test.sh b/scripts/run_single_test.sh index 550f4d64..3c8294f5 100755 --- a/scripts/run_single_test.sh +++ b/scripts/run_single_test.sh @@ -1,2 +1,2 @@ -#!/bin/sh +#!/usr/bin/env sh python3 -m pytest -rfpsxEX --disable-warnings -vv -k test_run_omr_marker_mobile