GIMP 3.0.6: Crafting a Favicon Generator Plugin on Windows 11
There have been changes to how plugins are coded for GIMP in the 3.0 series. This is not an official guide, but rather an experimental walkthrough for plugin development in GIMP. Experimenting with Python plugins can be rewarding, and this particular plugin helps generate favicons quickly in the same folder as your working .xcf file.
Getting Started With Python Plugins in GIMP 3.0.6
GIMP 3.0 introduced major changes in its Python bindings. Plugins now use gi.repository.Gimp and Gio for modern image and file handling. Understanding this structure is essential for building effective plugins on Windows 11.
Preparation: Setting Up Your Coding Environment
- Install VSCodium as your Python editing environment.
- In GIMP, go to Preferences → Folders → Plugins and add a custom directory for storing your Python scripts.
- Make note of this directory and create a VSCodium workspace pointing to it.
- Open the workspace in VSCodium and start crafting your Python files.
- During testing and debugging, always close and reopen GIMP after changes to the plugin, so it properly reloads your Python scripts.
1. Plugin Folder Setup
Place your Python plugin(s) into the custom plugin folder mentioned above. From within GIMP, go to (Preferences → Folders → Plugins) and confirm that location truly matches your VSCodium workspace area.
Important: Each plugin must live in its own folder — GIMP 3 will not recognize the plugin file if it is directly in the plugins directory. Example:
C:\Users\<username>\Documents\My-GIMP-Plugins\my_favicon_generator\my_favicon_generator.pyNotice that my_favicon_generator.py is inside its own folder my_favicon_generator. Even if your Python code is perfectly written, placing the .py file directly under the custom plugins folder will prevent it from showing up in GIMP.
2. Plugin Structure
A GIMP Python plugin requires a class extending Gimp.PlugIn, with the following methods:
do_query_procedures()— registers procedure name.do_create_procedure()— sets menu, documentation, attribution.run()— main logic executed when plugin runs.
class FaviconGenerator(Gimp.PlugIn):
def do_query_procedures(self):
return ["plug-in-favicon-generator"]
def do_create_procedure(self, name):
procedure = Gimp.ImageProcedure.new(self, name, Gimp.PDBProcType.PLUGIN, self.run, None)
procedure.add_menu_path('<Image>/Filters/Development/Python-Fu/')
return procedure
def run(self, procedure, run_mode, image, drawables, config, run_data):
pass3. Handling Images and Layers
Modern GIMP 3 plugins require you to work with image.duplicate() for safe manipulation, and access layers through drawables. Always check that the image is saved, so you have a valid folder path.
dup = image.duplicate()
dup.scale(32, 32)
export_path = os.path.join(folder_path, 'favicon-32.png')4. Exporting Favicons
GIMP 3 requires the file-png-export procedure instead of the old file-png-save. Use a Gio.File object and configure proc.run(config) to export non-interactively:
gfile = Gio.File.new_for_path(export_path)
pdb = Gimp.get_pdb()
proc = pdb.lookup_procedure('file-png-export')
config = proc.create_config()
config.set_property('run-mode', Gimp.RunMode.NONINTERACTIVE)
config.set_property('image', dup)
config.set_property('file', gfile)
proc.run(config)5. Looping Through Sizes
To generate multiple favicons (16, 32, 48, 64), loop over sizes, duplicate the image for each, scale, export, and delete the duplicate to free memory:
sizes = [16, 32, 48, 64]
for size in sizes:
dup = image.duplicate()
dup.scale(size, size)
# export logic here
dup.delete()6. Informing the User
Use Gimp.message() to show a pop-up with the export folder or errors. This is crucial for plugin feedback, especially for new users experimenting:
Gimp.message(f'Favicons generated in:\n{folder_path}')7. Full Working Example
There is a lot going on here to help conclude this favicon process, so learn and relearn from steps mentioned in this article. Below is the full code.
#!/usr/bin/env python3
import gi
gi.require_version('Gimp', '3.0')
from gi.repository import Gimp, GLib, Gio
import os
import sys
# Localization functions (for GIMP _() style messages)
def N_(message): return message
def _(message): return GLib.dgettext(None, message)
class FaviconGenerator(Gimp.PlugIn):
# Tell GIMP what procedures this plugin provides
def do_query_procedures(self):
return ["plug-in-favicon-generator"]
# Define the actual procedure with menu location, documentation, etc.
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("Favicon Generator")
procedure.add_menu_path('<Image>/Filters/Development/Python-Fu/')
procedure.set_documentation("Generate favicons from current image", "Generates multiple PNG favicons", name)
procedure.set_attribution("Kensley", "Kensley", "2026")
return procedure
# Main function that runs when user clicks the menu item
def run(self, procedure, run_mode, image, drawables, config, run_data):
try:
file_obj = image.get_file()
if not file_obj:
Gimp.message("Please save image as .xcf first.")
return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR, GLib.Error())
folder_path = os.path.dirname(file_obj.get_path())
sizes = [16, 32, 48, 64]
for size in sizes:
dup = image.duplicate()
dup.scale(size, size)
layers = dup.get_layers()
if not layers:
dup.delete()
continue
export_path = os.path.join(folder_path, f"favicon-{size}.png")
gfile = Gio.File.new_for_path(export_path)
pdb = Gimp.get_pdb()
proc = pdb.lookup_procedure("file-png-export")
config = proc.create_config()
config.set_property("run-mode", Gimp.RunMode.NONINTERACTIVE)
config.set_property("image", dup)
config.set_property("file", gfile)
proc.run(config)
dup.delete()
Gimp.message(f"Favicons generated in:\n{folder_path}")
except Exception as e:
Gimp.message(f"Error in Favicon Generator:\n{str(e)}")
return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR, GLib.Error())
return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
# Register the plugin with GIMP
Gimp.main(FaviconGenerator.__gtype__, sys.argv)Why this approach is powerful: Users no longer need to manually draft favicons from their .xcf files. Simply open the GIMP file, select the final composite layer representing the favicon, then go to Filters → Development → Python-Fu → my_favicon_generator and click. This becomes a powerhouse workflow, especially when generating many favicons across multiple web projects, saving significant time and effort.
Conclusion
This experimental plugin demonstrates the key concepts of modern Python plugin development for GIMP 3.0.6. Users on Windows 11 can use it to quickly generate favicons from any saved .xcf file, while learning how to structure their own plugins, use the procedure database, handle images safely, and provide user feedback. Experimentation like this is highly encouraged for building more complex and useful GIMP plugins in the future.