GIMP 3.0.6: Expanding the Favicon Plugin into a Full Web Icon Generator
In the first part of this article series, we built a working Python plugin that automatically generates favicons from a GIMP .xcf project file. That alone can save a tremendous amount of time. In this second part, we take the concept further by expanding the plugin into a full web icon generator capable of exporting icons used across modern browsers, mobile devices, and progressive web apps.
Why Expand the Plugin?
While traditional favicons only required a few sizes, modern websites often require several additional icons for different devices and operating systems. Instead of exporting these manually, a plugin can generate them all instantly from the same source design.
Modern websites frequently include icons for:
- Browser tabs and bookmarks
- Windows shortcuts
- Apple iOS home screen icons
- Android Progressive Web App icons
By expanding our plugin, we can generate all of these automatically with a single click.
Modern Web Icon Sizes
The updated plugin will export several additional icons commonly used in modern web projects:
These icons support most modern browsers and mobile platforms without needing external favicon generation tools.
Design Requirement: Square Source Images
Before exporting icons, it is important that the design inside your GIMP project is square. Favicons and web icons rely on a 1:1 aspect ratio. If the source image is not square, the exported icons will appear distorted.
The updated plugin now includes a validation check that ensures the image width and height are equal before exporting any icons.
width = image.get_width()
height = image.get_height()
if width != height:
Gimp.message("Image must be square for icon generation.")
Using a Scalable Icon Map
Instead of manually writing export code for each icon, the plugin uses a simple dictionary that maps filenames to their target sizes. This makes the plugin easy to expand later if new icon standards appear.
Each entry represents a file that will be exported using the same process we built in Part One — duplicate the image, scale it, export it, and then delete the duplicate to preserve memory.
Full Plugin Example
Below is the expanded version of the plugin that generates both traditional favicons and modern mobile web icons.
#!/usr/bin/env python3
import gi
gi.require_version('Gimp', '3.0')
from gi.repository import Gimp, GLib, Gio
import os
import sys
# Localization helpers
def N_(message): return message
def _(message): return GLib.dgettext(None, message)
class WebIconGenerator(Gimp.PlugIn):
# Register plugin procedure
def do_query_procedures(self):
return ["plug-in-web-icon-generator"]
# Define plugin metadata and menu placement
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("Web Icon Generator")
procedure.add_menu_path('<Image>/Filters/Development/Python-Fu/')
procedure.set_documentation(
"Generate modern web icons",
"Exports favicon, Apple, and Android icons from the current image.",
name
)
procedure.set_attribution("Kensley", "Kensley", "2026")
return procedure
# Main execution
def run(self, procedure, run_mode, image, drawables, config, run_data):
try:
# Ensure the image has been saved so we know where to export
file_obj = image.get_file()
if not file_obj:
Gimp.message("Please save the image as .xcf first.")
return procedure.new_return_values(
Gimp.PDBStatusType.CALLING_ERROR, GLib.Error()
)
folder_path = os.path.dirname(file_obj.get_path())
# Ensure the image is square (important for icons)
width = image.get_width()
height = image.get_height()
if width != height:
Gimp.message("Image must be square for icon generation.")
return procedure.new_return_values(
Gimp.PDBStatusType.CALLING_ERROR, GLib.Error()
)
# Define all icons we want to generate
icon_map = {
"favicon-16.png": 16,
"favicon-32.png": 32,
"favicon-48.png": 48,
"favicon-64.png": 64,
"apple-touch-icon.png": 180,
"android-chrome-192.png": 192,
"android-chrome-512.png": 512
}
pdb = Gimp.get_pdb()
proc = pdb.lookup_procedure("file-png-export")
for filename, size in icon_map.items():
# Duplicate original image
dup = image.duplicate()
# Resize duplicate
dup.scale(size, size)
export_path = os.path.join(folder_path, filename)
gfile = Gio.File.new_for_path(export_path)
# Configure export
cfg = proc.create_config()
cfg.set_property("run-mode", Gimp.RunMode.NONINTERACTIVE)
cfg.set_property("image", dup)
cfg.set_property("file", gfile)
# Run export
proc.run(cfg)
# Clean memory
dup.delete()
Gimp.message(f"Web icons generated in:
{folder_path}")
except Exception as e:
Gimp.message(f"Error in Web Icon Generator:
{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(WebIconGenerator.__gtype__, sys.argv)
End Result
- favicon-16.png
- favicon-32.png
- favicon-48.png
- favicon-64.png
- apple-touch-icon.png
- android-chrome-192.png
- android-chrome-512.png
- No need for external favicon generators.
- Maintain a single master design inside your
.xcffile. - Ensure the design is square.
- Select the final composite layer.
- Run Filters → Development → Python-Fu → Web Icon Generator.
- All modern web icons export instantly to the same project folder.
Conclusion
Expanding a simple favicon generator into a full web icon exporter demonstrates how powerful GIMP's Python plugin system can be. By automating repetitive export tasks, designers and developers can focus more on crafting strong visual assets rather than manually generating multiple icon sizes. This workflow becomes especially valuable when managing multiple web projects where consistency and speed are critical.