from PIL import Image
import os
import argparse
from pathlib import Path
def resize_image_with_aspect_ratio(input_path, output_path, max_width, max_height, quality=85):
"""
Resize an image while maintaining its aspect ratio.
Args:
input_path (str): Path to the input image
output_path (str): Path where resized image will be saved
max_width (int): Maximum width for resized image
max_height (int): Maximum height for resized image
quality (int): JPEG quality (1-100, default: 85)
Returns:
tuple: (original_size, new_size) or None if failed
"""
try:
# Open the image
with Image.open(input_path) as img:
original_size = img.size
# Calculate the aspect ratio
img.thumbnail((max_width, max_height), Image.Resampling.LANCZOS)
new_size = img.size
# Save the resized image
img.save(output_path, optimize=True, quality=quality)
return original_size, new_size
except Exception as e:
print(f"Error processing {input_path}: {e}")
return None
def batch_resize_images(input_dir, output_dir, max_width, max_height, quality=85):
"""
Resize all images in a directory while preserving aspect ratios.
Args:
input_dir (str): Directory containing images to resize
output_dir (str): Directory to save resized images
max_width (int): Maximum width for resized images
max_height (int): Maximum height for resized images
quality (int): JPEG quality (1-100, default: 85)
"""
# Supported image formats
supported_formats = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp'}
# Create output directory if it doesn't exist
Path(output_dir).mkdir(parents=True, exist_ok=True)
# Process each image in the input directory
processed_count = 0
input_path = Path(input_dir)
for file_path in input_path.iterdir():
if file_path.suffix.lower() in supported_formats:
output_file = Path(output_dir) / file_path.name
result = resize_image_with_aspect_ratio(
str(file_path),
str(output_file),
max_width,
max_height,
quality
)
if result:
original_size, new_size = result
print(f"Processed: {file_path.name}")
print(f" Original: {original_size[0]}x{original_size[1]} -> Resized: {new_size[0]}x{new_size[1]}")
processed_count += 1
print(f"\nCompleted! Processed {processed_count} images.")
def main():
parser = argparse.ArgumentParser(description="Resize images while maintaining aspect ratio")
parser.add_argument("input_dir", help="Input directory containing images")
parser.add_argument("output_dir", help="Output directory for resized images")
parser.add_argument("--width", type=int, default=1920, help="Maximum width (default: 1920)")
parser.add_argument("--height", type=int, default=1080, help="Maximum height (default: 1080)")
parser.add_argument("--quality", type=int, default=85, help="JPEG quality 1-100 (default: 85)")
args = parser.parse_args()
if not os.path.exists(args.input_dir):
print(f"Error: Input directory '{args.input_dir}' does not exist")
return
batch_resize_images(
args.input_dir,
args.output_dir,
args.width,
args.height,
args.quality
)
if __name__ == "__main__":
main()
This script provides an automatic image resizing solution that maintains the original aspect ratio of images. It prevents distortion by calculating appropriate dimensions that fit within your specified maximum width and height constraints while preserving the image’s proportions.
The script includes two main functions:
resize_image_with_aspect_ratio(): Resizes a single image while maintaining aspect ratiobatch_resize_images(): Processes all images in a directory with the same resizing rulespip install Pillow
python image_resizer.py /path/to/input/images /path/to/output/images
python image_resizer.py /input/dir /output/dir --width 1200 --height 800 --quality 90
This tool solves the common problem of needing to resize images for web use, social media, or storage optimization without manually adjusting each image. It’s particularly valuable for:
The aspect ratio preservation ensures that all resized images maintain their original proportions, resulting in professional-looking outputs that aren’t distorted.