design

GIMP 3.0.8: A Simple, Scalable Watermark Plugin for GIMP 3

2026-03-14 design 2 min read

If you successfully launched my full web icon generator plugin, then try this one out. We'll now introduce a Python plugin for GIMP 3.0.8 that makes it easy to add watermarks to any image. Instead of manually creating new layers and adjusting their position and opacity, this plugin automates the entire process, including scaling the watermark proportionally to the image size.

Why Automate Watermarks?

Watermarking images manually can be time-consuming, especially if you have hundreds of files or need consistent placement and opacity. Automating this with a plugin ensures:

  • Consistent positioning near the bottom of each image
  • Proportional scaling based on image size
  • Custom opacity and margins
  • Quick, repeatable workflow across multiple images

Plugin Features

  • Load any PNG watermark (designed beforehand)
  • Auto-scale watermark as a percentage of image width
  • Set custom opacity
  • Center horizontally and place near the bottom with margin control
  • Runs from Filters → Development → Python-Fu → Apply Watermark

Load Your Watermark

The plugin requires a PNG file for the watermark. Make sure your watermark is already designed and you know its file path, so it can be properly injected into the plugin code. Replace the placeholder below with your own path:

python
				 
watermark_path = r"C:\path\to\your\watermark.png"
			

Scaling and Positioning

You can adjust the watermark size relative to the target image using a simple percentage. For example, to make the watermark 25% of the image width:

python
				 
watermark_width_percent = 25
			

The plugin automatically calculates the height to maintain the watermark's aspect ratio, and then inserts it centered horizontally near the bottom of the image.

Full Plugin Code

Below is the complete Python plugin for GIMP 3.0.6:

python
				 
#!/usr/bin/env python3
import gi
gi.require_version("Gimp", "3.0")
from gi.repository import Gimp, GLib, Gio
import os
import sys

class WatermarkStamp(Gimp.PlugIn):

    def do_query_procedures(self):
        return ["plug-in-watermark-stamp"]

    def do_create_procedure(self, name):
        procedure = Gimp.ImageProcedure.new(
            self, name, Gimp.PDBProcType.PLUGIN, self.run, None
        )
        procedure.set_image_types("*")
        procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.DRAWABLE)
        procedure.set_menu_label("Apply Watermark")
        procedure.add_menu_path("<Image>/Filters/Development/Python-Fu/")
        procedure.set_documentation(
            "Apply watermark to image",
            "Adds a centered watermark near the bottom of the image, auto-scaled to fit.",
            name
        )
        procedure.set_attribution("Kensley", "Kensley", "2026")
        return procedure

    def run(self, procedure, run_mode, image, drawables, config, run_data):
        try:
            # -------- CONFIG --------
            watermark_path = r"C:\path\to\your\watermark.png"  # Replace with your watermark
            opacity = 30
            bottom_margin = 80
            watermark_width_percent = 25  # Width of watermark as a percentage of image width
            # ------------------------

            if not os.path.exists(watermark_path):
                Gimp.message("Watermark image not found.")
                return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR, GLib.Error())

            pdb = Gimp.get_pdb()

            # Load watermark
            gfile = Gio.File.new_for_path(watermark_path)
            load_proc = pdb.lookup_procedure("file-png-load")
            load_cfg = load_proc.create_config()
            load_cfg.set_property("run-mode", Gimp.RunMode.NONINTERACTIVE)
            load_cfg.set_property("file", gfile)
            result = load_proc.run(load_cfg)
            watermark_img = result.index(1)

            # Get first layer
            watermark_layer = watermark_img.get_layers()[0]

            # --- SCALE WATERMARK ---
            img_w = image.get_width()
            target_width = int(img_w * (watermark_width_percent / 100))
            scale_factor = target_width / watermark_layer.get_width()
            new_height = int(watermark_layer.get_height() * scale_factor)
            watermark_layer.scale(target_width, new_height)

            # --- INSERT INTO IMAGE ---
            wm_layer = Gimp.Layer.new_from_drawable(watermark_layer, image)
            image.insert_layer(wm_layer, None, -1)
            watermark_img.delete()

            # Set opacity
            wm_layer.set_opacity(opacity)

            # Center horizontally and place near bottom
            wm_w = wm_layer.get_width()
            wm_h = wm_layer.get_height()
            x = int((img_w - wm_w) / 2)
            y = int(image.get_height() - wm_h - bottom_margin)
            wm_layer.set_offsets(x, y)

            Gimp.displays_flush()
            Gimp.message("Watermark applied successfully!")

        except Exception as e:
            Gimp.message(f"Error applying watermark:
{str(e)}")
            return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR, GLib.Error())

        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())

# Register plugin
Gimp.main(WatermarkStamp.__gtype__, sys.argv)
			

End Result

After running the plugin, your image will have a properly scaled watermark automatically applied near the bottom. You can adjust opacity, bottom margin, and width percentage directly in the configuration section of the plugin code for complete customization.

Workflow Advantage:
  • No need to manually add watermark layers.
  • Watermarks are automatically scaled and positioned consistently.
  • Quickly process multiple images by running the plugin on each one.
  • Adjust width percentage, opacity, and margins directly in the code.

Conclusion

By using this GIMP plugin, developers and designers can automate watermarking across multiple images, saving time and ensuring consistent placement and sizing. The plugin demonstrates the flexibility of Python scripting in GIMP 3, allowing for fast, repeatable workflows that would otherwise require manual effort.