Batch Resize and Watermark Photos in GIMP with Python

Automating repetitive image editing tasks saves time and ensures consistency across large image sets. This guide provides a complete Python-Fu script for GIMP to batch-process an entire folder of photos, scaling each image to fit specific dimensions while preserving aspect ratios, applying a customized text watermark, and saving the results to an output directory.

Setting Up the Script

GIMP provides a built-in Python environment known as Python-Fu, which accesses GIMP’s Procedural Database (PDB).

To install the script:

  1. Locate your GIMP plug-ins folder by navigating to Edit > Preferences > Folders > Plug-ins.
  2. Create a new file named batch_resize_watermark.py inside that folder.
  3. On Linux or macOS, make the script executable by running chmod +x batch_resize_watermark.py in your terminal.
  4. Paste the Python script below into the file and restart GIMP.

The Python-Fu Script

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
from gimpfu import *

def batch_resize_and_watermark(input_dir, output_dir, max_width, max_height, watermark_text):
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    valid_extensions = ('.png', '.jpg', '.jpeg', '.tiff', '.bmp')
    files = [f for f in os.listdir(input_dir) if f.lower().endswith(valid_extensions)]

    for filename in files:
        input_path = os.path.join(input_dir, filename)
        output_path = os.path.join(output_dir, filename)

        # Load the image
        image = pdb.gimp_file_load(input_path, input_path)
        
        # Calculate aspect-ratio-preserving dimensions
        orig_width = image.width
        orig_height = image.height
        ratio = min(float(max_width) / orig_width, float(max_height) / orig_height)
        
        # Only downscale if the image exceeds the target bounds
        if ratio < 1.0:
            new_width = int(orig_width * ratio)
            new_height = int(orig_height * ratio)
            pdb.gimp_image_scale(image, new_width, new_height)
        else:
            new_width = orig_width
            new_height = orig_height

        # Create the watermark layer
        font_size = max(16, int(new_height * 0.03))  # 3% of image height
        text_layer = pdb.gimp_text_fontname(
            image, 
            None, 
            0, 
            0, 
            watermark_text, 
            10, 
            True, 
            font_size, 
            PIXELS, 
            "Sans"
        )

        # Set watermark appearance and position
        pdb.gimp_layer_set_opacity(text_layer, 50.0)  # 50% opacity
        
        # Position in bottom-right corner with padding
        padding = 15
        pos_x = new_width - text_layer.width - padding
        pos_y = new_height - text_layer.height - padding
        pdb.gimp_layer_set_offsets(text_layer, max(0, pos_x), max(0, pos_y))

        # Merge layers and save
        merged_layer = pdb.gimp_image_flatten(image)
        pdb.gimp_file_save(image, merged_layer, output_path, output_path)

        # Clean up image from memory
        pdb.gimp_image_delete(image)

register(
    "python_fu_batch_resize_watermark",
    "Batch Resize and Watermark",
    "Batch-resizes photos and adds a watermark to an output directory.",
    "Author",
    "Open Source",
    "2024",
    "<Image>/Filters/Batch/Resize and Watermark...",
    "",
    [
        (PF_DIRNAME, "input_dir", "Input Folder", ""),
        (PF_DIRNAME, "output_dir", "Output Folder", ""),
        (PF_INT, "max_width", "Max Width (px)", 1920),
        (PF_INT, "max_height", "Max Height (px)", 1080),
        (PF_STRING, "watermark_text", "Watermark Text", "© My Studio")
    ],
    [],
    batch_resize_and_watermark
)

main()

How the Script Works

  1. File Scanning: The script uses Python's os library to iterate over image files matching common file formats (.jpg, .png, .jpeg, .tiff, .bmp) within the target directory.
  2. Proportional Rescaling: pdb.gimp_image_scale dynamically scales the image downward if its dimensions exceed the defined boundaries, maintaining the original aspect ratio without distortion.
  3. Text Watermarking: pdb.gimp_text_fontname creates a new text layer. The script calculates font size relative to image height, shifts layer opacity to 50% using pdb.gimp_layer_set_opacity, and offsets the text to the bottom-right corner.
  4. Flatten and Export: pdb.gimp_image_flatten combines all layers before pdb.gimp_file_save writes the finalized file into the designated output folder.
  5. Memory Management: pdb.gimp_image_delete purges each processed image from GIMP's memory cache, preventing memory leaks during large batch runs.

Running the Tool

Once installed, the script appears in GIMP under Filters > Batch > Resize and Watermark.... Select the source directory, output destination, maximum bounds, and watermark text, then click OK to begin processing.