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.
Revisit

GIMP Basics

Keyboard shortcuts and toolbox reference.

Extend GIMP

Plugins & Extensions

G'MIC, BIMP batch processor, and more.