Python Script to Optimise folder of Images for Website

Whether you’re a web developer, a content creator, or simply someone who manages a lot of images, optimising your image files is crucial for faster load times and reduced storage.

This Python script is a handy tool for bulk-optimising all image files within a folder and its subfolders.

The script will:

  • resizes images down to 1000 pixels (if needed),
  • compresses them for web quality, and
  • saves them in a new “optimised” folder – complete with any subfolders.

The original files are unchanged.

Requirements

  • Python 3.x
  • Pillow (Python Imaging Library Fork)
  • argparse (Built-in Python library)

To install Pillow, run:

pip install Pillow

About the Script

  1. Command-Line Directory Input: The script starts by accepting a directory path as a command-line argument. This directory and its subfolders will be scanned for image files to optimize.
  2. Folder Structure Preservation: As the script traverses through the directory and its subdirectories, it creates a corresponding folder structure in a new “optimised” folder. This ensures that the optimized images maintain the original folder hierarchy.
  3. Image Identification and Processing: The script identifies image files with extensions .png, .jpg, and .jpeg. For each image:
    1. If the width is greater than 1000 pixels, it’s resized to a maximum width of 1000 pixels while maintaining the aspect ratio.
    2. Regardless of the size, every image is compressed for web quality.
  4. Error Handling: If the script encounters an error while processing an image, it copies the original image to the “optimised” folder and continues with the next image.
  5. Progress Monitoring: During the optimization, the script outputs the name of the last file processed and its individual compression percentage to give real-time updates on the progress.
  6. Final Summary: At the end, the script provides a summary that includes the total number of files processed, the total size saved in MB, and the overall percentage of size compressed.

How to Run the Script

Save the script in a file, say ImageOptimizer.py, and run it from the command line as follows:

python ImageOptimizer.py /path/to/directory

This will start the optimisation process for all image files within the specified directory and its subfolders.

The Script

Here’s the complete Python script for this task:

from PIL import Image, ImageResampling
import os
import shutil
import argparse

# Initialize variables
num_files_processed = 0
total_size_saved = 0

# Parse command-line arguments
parser = argparse.ArgumentParser(description='Optimise images in a folder and its subfolders.')
parser.add_argument('directory', type=str, help='The directory containing images to be optimised')
args = parser.parse_args()

# Main function to optimize images
def optimize_images(directory):
    global num_files_processed
    global total_size_saved

    for root, dirs, files in os.walk(directory):
        new_root = root.replace(directory, os.path.join(directory, 'optimised'))
        os.makedirs(new_root, exist_ok=True)

        for file in files:
            if file.lower().endswith(('.png', '.jpg', '.jpeg')):
                num_files_processed += 1
                original_file_path = os.path.join(root, file)
                optimised_file_path = os.path.join(new_root, file)

                try:
                    with Image.open(original_file_path) as img:
                        initial_size = os.path.getsize(original_file_path)

                        # Resize if width is greater than 1000
                        if img.width > 1000:
                            img = img.resize((1000, int((1000 / img.width) * img.height)), ImageResampling.LANCZOS)

                        # Save all images optimized for web quality
                        img.save(optimised_file_path, quality=85)

                        final_size = os.path.getsize(optimised_file_path)
                        size_saved = initial_size - final_size
                        total_size_saved += size_saved

                        # Print progress
                        individual_compression_percentage = (size_saved / initial_size) * 100 if initial_size > 0 else 0
                        print(f"Processed: {file}, Compression: {individual_compression_percentage:.2f}%")

                except Exception as e:
                    print(f"Error occurred: {e}. Copying original image.")
                    shutil.copy2(original_file_path, optimised_file_path)

# Execute the optimization
if __name__ == "__main__":
    optimize_images(args.directory)

    # Output statistics
    compression_percentage = (total_size_saved / (total_size_saved + total_size_saved)) * 100

    print(f"\nTotal files processed: {num_files_processed}")
    print(f"Total size saved: {total_size_saved / 1024 / 1024:.2f} MB")
    print(f"Overall compression percentage: {compression_percentage:.2f}%")