# Batch Image Resizer

This utility processes a directory of images, resizing them to fit within specified dimensions while maintaining their aspect ratio. It handles format conversion and creates the output directory if it doesn't exist.

**Modules Used:**
*   [[programming/python/modules/pillow-module|Pillow]]: For opening, resizing, and saving images.
*   [[programming/python/modules/argparse-module|argparse]]: To handle command-line arguments for dimensions and paths.
*   [[programming/python/modules/pathlib-module|pathlib]]: For robust file path handling.

## The Code

Save this as `resizer.py`.

```python
import argparse
from pathlib import Path
from PIL import Image

def resize_images(input_dir, output_dir, max_width, max_height, output_format):
    input_path = Path(input_dir)
    output_path = Path(output_dir)
    
    # Create output directory if it doesn't exist
    output_path.mkdir(parents=True, exist_ok=True)

    supported_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.gif', '.webp'}
    
    # Find images
    files = [f for f in input_path.iterdir() if f.is_file() and f.suffix.lower() in supported_extensions]
    print(f"Found {len(files)} images in '{input_dir}'")

    for file in files:
        try:
            with Image.open(file) as img:
                # Use thumbnail() to resize in place, maintaining aspect ratio
                # It will not scale up images smaller than the target size
                img.thumbnail((max_width, max_height))
                
                # Determine output filename
                new_suffix = f".{output_format}" if output_format else file.suffix
                save_name = file.stem + new_suffix
                save_path = output_path / save_name
                
                # Handle transparency for JPEG (convert RGBA to RGB)
                if new_suffix.lower() in ['.jpg', '.jpeg'] and img.mode in ('RGBA', 'P'):
                    img = img.convert('RGB')
                
                img.save(save_path)
                print(f"Processed: {file.name} -> {save_name} ({img.size[0]}x{img.size[1]})")
                
        except Exception as e:
            print(f"Error processing {file.name}: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Batch Image Resizer")
    parser.add_argument("input", help="Input directory containing images")
    parser.add_argument("output", help="Output directory for resized images")
    parser.add_argument("--width", type=int, default=800, help="Maximum width (default: 800)")
    parser.add_argument("--height", type=int, default=800, help="Maximum height (default: 800)")
    parser.add_argument("--format", help="Convert to specific format (e.g., jpg, png)")
    
    args = parser.parse_args()
    
    resize_images(args.input, args.output, args.width, args.height, args.format)
```

## Usage

```bash
# Resize images to fit within 800x800 (default)
python resizer.py ./raw_photos ./web_ready

# Resize to 200x200 thumbnails and convert to PNG
python resizer.py ./photos ./thumbnails --width 200 --height 200 --format png
```

[[programming/python/python]]