GIMP Script-Fu and Python-Fu: Batch Processing and Automation Guide

Learn to write Script-Fu and Python-Fu scripts to automate batch operations, process hundreds of images, and extend GIMP's capabilities.

πŸ“‹

Want ready-to-run scripts?

Browse the Script-Fu Snippet Library - 71 copy-paste scripts for batch processing, layer operations, color adjustments, and more. No setup needed.

Browse Snippets β†’
Advanced ~65 min read Updated May 2026

Time Saved by Automating Common Tasks

Estimated time per 100 images - Manual vs scripted

What is Script-Fu?

Script-Fu is GIMP's built-in scripting language, based on Scheme (a dialect of Lisp). It provides access to all of GIMP's internal functions - Everything you can do via the GUI, you can do with a script.

Script-Fu is ideal for:

  • Batch processing - Apply the same operation to hundreds of images automatically
  • Consistent watermarking, resizing, or exporting for social media workflows
  • Creating reusable effects or procedures you apply regularly
  • Automating complex multi-step operations that would take minutes by hand
  • Building custom GIMP menu items and tools

Script-Fu (Scheme)

  • Built into GIMP - No installation needed
  • Based on Scheme (functional, parenthesis-heavy syntax)
  • Runs inside GIMP process
  • Good for simple automation
  • Access via Filters β†’ Script-Fu β†’ Console

Python-Fu

  • Requires Python 3 installation
  • Familiar Python syntax - Easier for most programmers
  • Better file handling and external library support
  • Good for complex batch operations
  • Access via Filters β†’ Python-Fu β†’ Console

Using the Script-Fu Console

The Script-Fu Console lets you run scripts interactively - Great for experimenting and learning.

Open it via: Filters β†’ Script-Fu β†’ Console

Script-Fu Console
; Get the current image
> (car (gimp-file-load RUN-NONINTERACTIVE "/path/to/image.png" "image.png"))
1
; Get image width
> (car (gimp-image-width (car (gimp-display-get-image (car (gimp-display-list))))))
1920
; Flatten and export current image
> (gimp-image-flatten image)
(0)
Input:
|

Essential Console Commands to Try

Command What it does
(gimp-version) Returns the GIMP version string
(car (gimp-display-list)) Returns the ID of the first open display
(gimp-image-list) Lists all open images by ID
(gimp-image-width image) Returns the width of the image in pixels
(gimp-image-height image) Returns the height of the image
(gimp-image-get-active-drawable image) Returns the active layer/drawable
(gimp-drawable-desaturate drawable DESATURATE-LUMINOSITY) Desaturate (greyscale) the active layer
(gimp-curves-spline drawable HISTOGRAM-VALUE 10 #(0 0 64 40 128 140 192 210 255 255)) Apply a curves adjustment

Scheme Syntax Primer

Scheme uses prefix notation and heavy parentheses. Every expression is a list: (function arg1 arg2 ...)

; Comments start with semicolon
(define my-var 42)
; Define a variable
(define (my-function x y) (+ x y))
; if/else
(if (> x 10) "big" "small")
; Let bindings (local variables)
(let* ((image (car (gimp-file-load ...))) (drawable (car (gimp-image-get-active-drawable image)))) ; use image and drawable here )
; Loop over a list
(for-each (lambda (file) (process-file file)) file-list)
Concept Scheme Syntax Python Equivalent
Variable (define x 10) x = 10
Function (define (add a b) (+ a b)) def add(a, b): return a + b
Conditional (if (> x 5) "big" "small") "big" if x > 5 else "small"
Loop (while condition body) while condition: body
List first item (car my-list) my_list[0]
List rest (cdr my-list) my_list[1:]
Print (gimp-message "hello") print("hello")

Your First Script: Resize & Export

This script resizes the current image to 800Γ—600 and exports it as JPEG. For a visual resizing tool without scripting, try our image resizer.

; Script: Resize current image to 800x600 and export as JPG
; Run from: Filters β†’ Script-Fu β†’ Console

(let* ((image (car (gimp-file-load
                  RUN-NONINTERACTIVE
                  "/path/to/your/image.png"
                  "image.png")))
       (drawable (car (gimp-image-get-active-drawable image))))

  ; Scale the image to 800x600
  (gimp-image-scale-full image 800 600 INTERPOLATION-LINEAR)

  ; Flatten all layers
  (gimp-image-flatten image)

  ; Export as JPEG at 85% quality
  (file-jpeg-save
    RUN-NONINTERACTIVE image
    (car (gimp-image-get-active-drawable image))
    "/path/to/output.jpg"
    "output.jpg"
    0.85 ; quality 0-1
    0 0 0 0 0 0 0)

  ; Clean up
  (gimp-image-delete image))
Tip: Replace /path/to/your/image.png with the actual file path. On Windows, use forward slashes or escape backslashes: C:/Users/name/image.png

Batch Resize - All Images in a Folder

This script resizes all PNG/JPG files in a source directory and saves them to an output directory. You can also convert between formats without scripting using our online tool.

; Batch resize: all images in input-dir β†’ output-dir at max 1200px wide
; Save this file as batch-resize.scm in your GIMP scripts folder

(define (batch-resize input-dir output-dir max-width)
  (let* ((filelist (cadr (file-glob
                     (string-append input-dir "/*.png")
                     1))))
    (for-each
      (lambda (filename)
        (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
               (orig-width  (car (gimp-image-width image)))
               (orig-height (car (gimp-image-height image)))
               (scale (if (> orig-width max-width)
                        (/ max-width orig-width)
                        1.0))
               (new-width  (round (* orig-width scale)))
               (new-height (round (* orig-height scale)))
               (basename (car (strbreakup (car (strbreakup filename "/")) ".")))
               (outfile (string-append output-dir "/" basename "-resized.jpg")))
          (gimp-image-scale-full image new-width new-height INTERPOLATION-CUBIC)
          (gimp-image-flatten image)
          (file-jpeg-save RUN-NONINTERACTIVE image
            (car (gimp-image-get-active-drawable image))
            outfile outfile 0.85 0 0 0 0 0 0 0)
          (gimp-image-delete image)))
      filelist)))

; Call it:
(batch-resize "/home/user/photos" "/home/user/output" 1200)

Batch Watermark

Add a text watermark to all images in a directory. Before watermarking, you may want to check your images for transparency to ensure the watermark renders correctly against all backgrounds.

; Add watermark text to all images in a directory

(define (add-watermark image watermark-text)
  (let* ((width  (car (gimp-image-width image)))
         (height (car (gimp-image-height image)))
         (text-layer (car (gimp-text-fontname
                        image -1           ; drawable (-1 = new layer)
                        20 20          ; x, y position
                        watermark-text
                        0             ; antialias
                        40            ; font size
                        UNIT-PIXEL
                        "Sans Bold"))))
    (gimp-layer-set-opacity text-layer 60)  ; 60% opacity
    (gimp-text-layer-set-color text-layer '(255 255 255))
    ; Move to bottom-right corner
    (let* ((tw (car (gimp-drawable-width text-layer)))
           (th (car (gimp-drawable-height text-layer))))
      (gimp-layer-set-offsets
        text-layer
        (- width tw 20)   ; 20px from right
        (- height th 20)))  ; 20px from bottom
    image))

Batch Format Convert (PNG β†’ WebP)

Convert all PNGs in a folder to WebP format - Ideal for web optimisation. You can also use our image compressor for quick one-off compressions without scripting.

; Batch convert PNG to WebP
; Requires GIMP 2.10+ with WebP support

(define (batch-png-to-webp input-dir output-dir quality)
  (let* ((filelist (cadr (file-glob
                     (string-append input-dir "/*.png") 1))))
    (for-each
      (lambda (filename)
        (let* ((image (car (gimp-file-load
                         RUN-NONINTERACTIVE filename filename)))
               (name-parts (strbreakup filename "/"))
               (basename   (car (strbreakup
                              (car (last-pair name-parts))
                              ".")))
               (outfile    (string-append output-dir "/" basename ".webp")))
          (gimp-image-flatten image)
          (file-webp-save RUN-NONINTERACTIVE image
            (car (gimp-image-get-active-drawable image))
            outfile outfile
            0        ; preset (0=default)
            quality  ; quality 0-100
            0 0 0 0 0 0)
          (gimp-image-delete image)))
      filelist)))

(batch-png-to-webp "/source" "/output" 85)

Python-Fu Alternative

If you prefer Python, the same batch resize operation is much more readable. Our dedicated Python-Fu scripting guide covers the setup and more advanced examples:

#!/usr/bin/env python3
# Python-Fu batch resize - Run from Filters β†’ Python-Fu β†’ Console
import os, gimp, gimpfu

def batch_resize(input_dir, output_dir, max_width):
    os.makedirs(output_dir, exist_ok=True)
    for fname in os.listdir(input_dir):
        if not fname.lower().endswith(('.png', '.jpg', '.jpeg')):
            continue
        fpath = os.path.join(input_dir, fname)
        image = gimp.pdb.gimp_file_load(fpath, fname)
        w = image.width
        h = image.height
        if w > max_width:
            scale = max_width / w
            image.scale(
                int(w * scale),
                int(h * scale)
            )
        image.flatten()
        out_name = os.path.splitext(fname)[0] + '-resized.jpg'
        out_path = os.path.join(output_dir, out_name)
        gimp.pdb.file_jpeg_save(
            image, image.active_drawable,
            out_path, out_name,
            0.85, 0, 0, 0, "", 0, 1, 0, 2, 0
        )
        gimp.pdb.gimp_image_delete(image)
    print(f"Done. Processed images saved to {output_dir}")

batch_resize("/home/user/photos", "/home/user/output", 1200)

Script-Fu Procedure Quick Reference

Task Script-Fu Procedure
Load image from file (gimp-file-load RUN-NONINTERACTIVE path path)
Get image width/height (gimp-image-width image) / (gimp-image-height image)
Scale image (gimp-image-scale-full image w h INTERPOLATION-CUBIC)
Flatten layers (gimp-image-flatten image)
Save as JPEG (file-jpeg-save RUN-NONINTERACTIVE image drawable path path quality 0 0 0 0 0 0 0)
Save as PNG (file-png-save RUN-NONINTERACTIVE image drawable path path 0 9 1 1 1 1 1)
Save as WebP (file-webp-save RUN-NONINTERACTIVE image drawable path path 0 85 0 0 0 0 0)
Add text (gimp-text-fontname image -1 x y text 0 size UNIT-PIXEL "Sans Bold")
Delete image from memory (gimp-image-delete image)
Apply Gaussian blur (plug-in-gauss RUN-NONINTERACTIVE image drawable rx ry method)
Brightness/contrast (gimp-brightness-contrast drawable brightness contrast)
Desaturate (gimp-drawable-desaturate drawable DESATURATE-LUMINOSITY)
Find any procedure: GIMP's built-in Procedure Browser (Filters β†’ Script-Fu β†’ Procedure Browser) lists every available function with its parameters and return values. Search for any keyword to discover relevant procedures.