Jump to content

Automating Image Resizing on macOS: A Python Script for the Efficient (and Lazy)


Recommended Posts

Posted

Hi everyone,

With the growing need for various image sizes for websites to deliver the correct size based on the device, manually exporting five photos became too tedious.

I took some time to create this small Python script, which runs under Python3 with Pillow. I’ve only tested it on macOS (Python installed via brew).

Verify Python3 Installation

First, ensure that Python3 is installed on your system by running the following command in your terminal:

which python3

The output should look something like this:

/opt/homebrew/bin/python3

If Python3 is not installed, you can install it using Homebrew.

Install Python3 (if needed)

If Python3 isn't installed yet, you can install it via Homebrew using the following command:

brew install python3

Install pipx and Pillow

You'll need pipx to manage Python packages. Install pipx using Homebrew, which will allow you to install and run Python packages easily in isolated environments:

brew install pipx

Once pipx is installed, use it to install the Pillow library, which is required for image processing in your script:

pipx install pillow

Now you're ready to run your Python script that uses Pillow for image resizing.

 

I created a directory containing the following folders:
- `/Users/{yourAccount}/AutomatImageSize/FilesIn` (I drop my large image files here, e.g., 3600x2400)
- `/Users/{yourAccount}/AutomatImageSize/FileOut` (my script creates each optimized version of the original and copies them here)
- `/Users/{yourAccount}/AutomatImageSize/archiveOriginal` (the script moves the original file here)

Supported extensions are: `.jpg`, `.jpeg`, `.png`, `.webp`

Since I’m quite lazy, I then used Automator to trigger the script whenever I drop a file into the `/Users/{yourAccount}/AutomatImageSize/FilesIn` folder.

If, like me, you use brew to manage your packages, in Automator, it’s better to use:

`/opt/homebrew/bin/python3 /Users/{UserName}/AutomatImageSize/creatImageP.py`

I hope this will be useful. Don’t forget to adjust the script with your own folders replace {userName} !
 

from PIL import Image
import os
import shutil

# Directory where images are dropped
input_folder = "/Users/{userName}/AutomatImageSize/FilesIn"

# Directory where resized images are saved
output_folder = "/Users/{userName}/AutomatImageSize/FilesOut"

# Directory where original images are archived
archive_folder = "/Users/{userName}/AutomatImageSize/archiveOriginal"

# Check if output and archive folders exist, if not, create them
if not os.path.exists(output_folder):
    os.makedirs(output_folder)

if not os.path.exists(archive_folder):
    os.makedirs(archive_folder)

# Resizing formats with their maximum sizes
formats = {
    "xs": 480,
    "sm": 640,
    "md": 1280,
    "lg": 1920,
    "xl": 2400  # Extra large size
}

# Maximum size of the original image (3600px)
max_original_size = 3600

# Supported file extensions
supported_extensions = ('.jpg', '.jpeg', '.png', '.webp')

# Function to resize the image while maintaining the aspect ratio
def resize_image(img, max_size):
    width, height = img.size

    # Detect if the image is in landscape or portrait mode and adjust accordingly
    if width > height:
        new_width = max_size
        new_height = int((height / width) * max_size)
    else:
        new_height = max_size
        new_width = int((width / height) * max_size)

    # Proportionally resize the image
    return img.resize((new_width, new_height), Image.LANCZOS)

# Iterate over all images in the input folder
for image_file in os.listdir(input_folder):
    # Check if the file has a supported extension
    if image_file.lower().endswith(supported_extensions):
        input_image = os.path.join(input_folder, image_file)

        # Open the original image
        with Image.open(input_image) as img:

            # 1. Iterate over the formats and apply proportional resizing
            for suffix, max_size in formats.items():
                img_resized = resize_image(img, max_size)

                # Keep the same format as the original image
                original_extension = os.path.splitext(image_file)[1].lower()
                output_path = f"{output_folder}/{os.path.splitext(image_file)[0]}-{suffix}{original_extension}"

                # Save in the original format
                img_resized.save(output_path, format=img.format)

            # 2. Create an optimized version of the original image in the output folder without suffix
            optimized_output_path = f"{output_folder}/{image_file}"
            img.save(optimized_output_path, format=img.format, quality=90, optimize=True)

            # 3. Move the original image to the archive folder without renaming it
            shutil.move(input_image, os.path.join(archive_folder, image_file))

If you're a Windows user, I'm sure it's *technically* possible to adapt this script... but honestly, I have only one thing to say: switch to Apple and get yourself a real tool! ;p

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.