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.
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
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 ...)
| 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:] |
| (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))
/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) |