Development version: GIMP 2.99.12 Released

GIMP 2.99.12 is a huge milestone towards GIMP 3.0. Many of the missing pieces are getting together, even though it is still a work in progress. As usual, issues are expected and in particular in this release which got important updates in major areas, such as canvas interaction code, scripts, but also theming…

CMYK space invasion - animated video-game like strip
CMYK space invasion”, by Jehan (based on GPLv3 code screencast), Creative Commons by-sa 4.0 - GIMP 2.99.12

The most noteworthy changes are listed below:

To get a more complete list of changes, you should refer to the NEWS file or look at the commit history.

Core Features

On-canvas brush sizing

There were requests for quickly changing tool settings, such as brush size or tool opacity, without having to go to the “Tool Options” dockable

A quickly appearing on-canvas GUI was considered (similar to other software), though we realized that many people who want this prefer a non workflow-disruptive interaction.

This is why we went for a simpler and direct design. For instance, now Alt + right click will trigger a brush resize action on canvas.

Changing brush size with Alt + right click
Changing brush size with Alt + right click - GIMP 2.99.12

Note that this code area still is a work-in-progress. There are more interactions still worked on, such as opacity update and customizability (see next section).

Customizable on-canvas modifiers

Many features are available on-canvas, some of them less known than others, for panning, zooming, rotating the canvas (since GIMP 2.10.0) or even selecting layers through canvas (since GIMP 2.10.10).

The current features are:

Modifiers Main button Secondary button (usually middle click) Third Button (usually right click)
- Tool-specific Panning Contextual menu
Ctrl/Cmd Tool-specific Zoom -
Shift Tool-specific Canvas rotation -
Shift-Ctrl/Shift-Cmd Tool-specific Constrained (15°) canvas rotation -
Alt Tool-specific Layer picking Resize brush (new)

Note: on macOS, Cmd is used in place of Ctrl. This is usually implied when Ctrl only is mentioned.

These are based on the following logic:

  • The main button is reserved for tools. Even though some of them share similar logic (e.g. all the selection tools share modifiers to add, subtract or intersect selections), some tools will have specific use cases.
  • The secondary button is used for “navigation”, in particular canvas navigation, but even on some kind of z axis with layer navigation (recent Layer picking ability since GIMP 2.10.10).
  • The third button was always reserved for contextual menu only. The new brush resizing ability breaks this tradition.

As we added new features, it became obvious that we were eventually going to lack modifiers for other useful actions. Also everyone is unique and has their own preferred workflow, so some people would definitely wish to have slightly different action behavior. As an example, even the just implemented brush sizing already comes in 2 variants (resize from center or sides).

Not to mention we had feedbacks of people disliking unexpected canvas changes, for instance because they hit Shift too early and a canvas rotation happens (admittedly not everyone cares about having canvas rotation in their workflow). Moreover some legacy actions, such as the contextual menu, can be questionable nowadays (especially as it is the same menu available at the top of the window).

This is why the canvas interaction code got factorized to use customizable modifiers rather than hard-coded. The table above is still the default, but now you may customize it: add more actions and modifiers, remove some or change them all. The settings are in Preferences > Canvas Interaction > Modifiers, then click on the button labelled “Click here to set a button’s modifiers” with any mouse or stylus button to start customize its modifiers.

You can even add “custom actions“, i.e. anything to which you could assign a shortcut. Want to swap the foreground/background color on right click? Now you can. Want to activate the Unified Transform tool with Shift-middle click and remove canvas rotation? You can too.

Remapping modifiers for on-canvas interactions
Remapping Shift+middle click to select the Unified Transform tool and removing Shift-Ctrl + middle click mapping - GIMP 2.99.12

Not only this, but it should work with any button (not only the second and third). So if you have a mouse with 20 buttons, you could map every one of them to an action (as well as any combination with modifiers).

Furthermore it will recognize different input devices, so that you can map different actions to the same button of several plugged mice or styli (note that it doesn’t recognize yet different device of the exact same model, but eventually it probably will).

⚠️ If you experience bugs in any canvas interaction, this is a good time to report them because a lot of code updates happened to make the code more generic so early-tester bugs are expected.

Testing new Zoom behaviors

A new settings is available in Preferences > Canvas Interaction to customize the zoom behavior, when zooming with Ctrl + middle click or Ctrl-Space.

The legacy algorithm would zoom, in or out, continuously as long as there is movement. It doesn’t depend on the movement span, which is why we called it the “By duration” drag-to-zoom behavior.

The new behavior is the “By distance” drag-to-zoom as it will zoom more if you do large moves, or in a more fine-grained way with very short moves. We left both behaviors available as a settings because after user testing, we decided that some people may prefer the old behavior, though the newly proposed one also made sense.

Finally the “Drag-to-zoom speed” allows you to set the speed rate at which the zoom will happen, in percentage of the default (i.e. that 100 is the default speed; you can raise or lower it).

These zoom settings were contributed by woob.

Improved tool pointers

In Preferences > Input Devices, you will first discover that some settings have been moved around. In particular, pointer-related settings have been moved from “Image Windows” to “Input Devices” tab and reorganized.

The second improvement is that the settings behavior have been rethought:

  • Now when “Show brush outline” is checked and “Show pointer for paint tools” is unchecked, if the brush outline cannot be drawn (for instance because you use a dynamics changing the size with pressure), GIMP will display a fallback 4-arcs generic outline showing the set size (it used to show a crosshair which made no sense, as “Show pointer” was explicitly unchecked).
  • When both “Show brush outline” and “Show pointer for paint tools” are unchecked, we show a minimal visual feedback of a few pixels only, as inconspicuous as possible, instead of a crosshair. Once again, people are explicitly asking for nothing, so showing a crosshair felt counter-productive. Yet actually showing nothing at all would be confusing too. Even with tablet displays, the parallax issue is unfortunately very real. This is why we opted for an extremely small point-like cursor. It still shows your exact position with few disturbance.

The point-like cursor was originally contributed by L Amander, then modified by Aryeom who made it visible on both dark and light background, and the new pointer was adapted into existing settings instead of creating a dedicated setting.

⚠️ This point-like cursor feature is really adapted for tablet displays and may seem very hard to use and frustrating for any other usage (nearly invisible pointer).

Drawing with point-like cursor
Drawing with point-like cursor: 🔎 can you see the pointer? 🔬 - GIMP 2.99.12

Improving again the “Fill by line art detection” of Bucket Fill tool

The “Fill by line art detection” mode of the Bucket Fill tool is a big question for us as we are regularly tweaking the options to improve usability.

The idea is how to make the settings easier to understand while not losing the very advanced capacity of the tool.

Therefore we tried something new, reorganizing the options in 3 categories which correspond to the 3 main steps of the line art algorithm:

  1. Line Art Detection: the settings which configure how the line art is detected: which source is being used? Using opacity or grayscale? Which threshold?
  2. Line Art Closure: the settings for the closure algorithm of opened line art areas.
  3. Fill Borders: the settings for borders of the fill: how much should we grow under the detected line art? How to get nicer borders?
Bucket Fill options - line art algorithm
3 steps in the line art algorighm: (1) line detection, (2) line closure, (3) border style - GIMP 2.99.12

Also we add an “Automatic closure” checkbox which is equivalent to setting the “Maximum gap length” to zero, and simply means we don’t want any smart closure by an algorithm. It is more understandable this way while making easier to switch between smart and no closure.

As a parallel, the option “Allow closing lines in selected layer” was renamed “Manual closure in fill layer“.

Finally we added a “Stroke borders” which works similarly as the “Stroke Path” or “Stroke Selection” features and which can be useful, in particular for visible borders of unclosed areas.

More iterations may happen to improve usability of this very nice tool as we progress towards GIMP 3.0.

Customizable checkerboard colors

In GIMP, we represent transparency in an image through the very common “checkerboard” pattern. In order to handle various use cases, we were proposing a series of colors, from light to dark grays, and even proposing white, gray or black only backgrounds. Though all these had the shared characteristics of being shades of gray.

Preferences > Display > Transparency > Check style has now a new option “Custom checks” allowing to select any RGB colors for the 2 colors representing “transparency”. If you wish to show transparency with rainbow 🌈 colors, this is up to you!

The new function gimp_checks_get_colors() has been added to the interface for plug-ins, replacing gimp_checks_get_shades(). This would allow any plug-in needing to render transparency checkerboard according to user choice.

This was originally contributed by Ben Rogalski, then improved, in particular for proper API and plug-in support.

Welcome Dialog

Remember the “Welcome dialog” which you get after an update (you probably got one in GIMP 2.99.12)? We worked a bit on the “Release Note” tab to allow for “demo” items. I.e. now some items (spotted with a different bullet point) will play a short scenario showing what a new feature refer to.

This is still a work-in-progress which doesn’t work for all types of features, and the styling for demo “playback” can definitely be improved. This is what it looks like right now:

Demo items
in release notes of Welcome dialog
Double-clicking demo items in release notes of Welcome dialog - GIMP 2.99.12

Pinching gesture for more usage

It was already possible to zoom the canvas with pinch gesture since GIMP 2.99.6. It is now also possible to rotate the canvas with a pinch gesture. Note that we made the choice to make zoom and rotation through pinch exclusive, i.e. that the first detected movement will lock on the gesture to either zoom or rotation, not both at the same time. It seemed to us that people might find it annoying to rotate when you just want to zoom (or the other way around).

Furthermore you can now zoom the preview images in item dockables (Layers, Channels, Paths) with pinching or mouse wheel.

Finally you can zoom in the Gradients dockable by pinch gesture too.

All of these were contributed by Povilas Kanapickas, who had already implemented zoom through pinch gesture on canvas.


This one deserved a section on its own in this news report because thanks to our new GSoC student, things moved quite fast here, not only for CMYK, but for the color space invasion project as a whole. We had to re-think a lot of the color conversions and display in various parts of the program.

Simulation data is now image data

The main usage of “simulation” is soft-proofing, a very common use case being printing. E.g. you could work in a RGB space, but know the final format (e.g. through a profile given to you by a printshop, often a CMYK profile) and want to see how your image would render, in particular regarding gamut loss.

It was already possible to set a “Soft proof profile“, as well as a rendering intent, and whether you wanted black point compensation or not. Yet this info was lost at each session restart.

These data will now be stored within the XCF file itself. So you won’t need to re-set them each time. Indeed if you work on a print job, the final target can be considered part of your workflow for this specific print job, hence part of the image.

As a consequence, these 3 information (soft proof profile, soft proof rendering intent and soft proof black point compensation) moved from the View > Color Management menu to the Image > Color Management menu (though View > Color management still contains some settings, such as whether to enable color management and whether or not to soft-proof; these are not image data but specific to a view: a same image can be simultaneously displayed in several views, one proofed and the other not, for instance).

Simulation toggle in the status bar

To make simulation a first-class citizen in your workflow, we wanted a way to make it obvious when you are viewing a proofed image or not. This is done through a new icon at the right of the status bar. This icon has 3 purposes:

  • It visually shows whether we are in simulation (a.k.a. soft-proofing) mode or not.
  • It allows to switch from simulation to non-simulated modes by clicking on it.
  • It allows to customize simulation settings (simulation profile, simulation rendering intent, black point compensation…) with a pop-up dialog by right-clicking.
changing soft-proofing settings with a toggle on status bar
Quickly enabling soft-proofing, clicking a toggle on status bar; or changing soft-proofing settings, right-clicking the same toggle (here showing a CC by-sa character design on canvas, by Aryeom) - GIMP 2.99.12

Various GUI now simulation-aware

Most GUIs which were displaying CMYK data were displaying “naive CMYK” colors. It is some generic algorithm not taking into account a specific CMYK color space.

Now if you set a simulation profile, and if this profile is a CMYK one, then these interface will display CMYK colors for this space, assuming that this is what you are interested in.

This includes interfaces such as the Color Picker tool, Sample Points, and the CMYK color selector.

Export formats with new or improved CMYK support

Similarly, several supported image formats have now new or improved CMYK support. We are not talking about having core CMYK support as backend encoding; GIMP is still only working in either *RGB, grayscale or indexed. Yet, you can now better import or export CMYK images in several formats, with much more suitable conversion done. In particular, it means that:

  • The CMYK profile of imported CMYK images will be stored as a simulation profile. I.e. that the image will now be RGB, yet the CMYK profile will be kept for simulation.
  • RGB images can be exported as CMYK, using the simulation profile (if a CMYK one) for conversion, then stored in the resulting CMYK file.

The assumption is always that the simulation profile is your target color space.

The updated formats so far are:


  • CMYK export now possible using the image Soft-proofing profile.
  • CMYK import ported to GEGL/babl conversion. The CMYK profile in the JPEG image will be stored as soft-proof profile on the image.


  • 8 and 16-bit CMYK(A) export now possible, using the image Soft-proofing profile.
  • CMYK import now possible. The CMYK profile in the TIFF image will be stored as Soft-proofing profile on the image.


  • CMYK import ported to GEGL/babl conversion. The CMYK profile in the PSD image will be stored as soft-proof profile on the image.

New plug-in API

Plug-ins can now request or set the soft-proofing profile of an image with new functions, such as gimp_image_get_simulation_profile() or gimp_image_set_simulation_profile() respectively. This is really a new image data which can and should be used by plug-ins when they want to display or process CMYK colors in the context of the active image.

Similarly several libgimpwidgets widgets (GimpColorNotebook, GimpColorSelection and GimpColorSelector) became simulation-aware with new dedicated functions to set the simulation space of interest.


GTK got a new CSS-like theming system in GTK+ 3, which means our 2.10 themes were not reusable and which is why we called for theme designers many times because a graphics application should really have a good set of neutral gray themes for an interface with the less color pollution possible, as it can affect your color perception.

It is only a month ago that we got a first proposal for a mid-gray neutral theme, though this one is still a work-in-progress. On the other hand, it triggered our long-term contributor, Akkana Peck, to propose a Light theme. With quick back-and-forth exchanges, this one was rapidly completed and merged into the source tree. Nikc helped also a lot by finding solutions to annoying bugs where we were stuck.

In the end, we made the theme more generic, making colors into variables with semantic names, and reused the same style code yet different colors to make a dark theme.

Instead of having 2 themes, we merged these into a “Default” theme with both a light and dark variants which will be switched depending on the “Use dark theme variant if available” checkbox.

For this to work, we also made a new process for theme makers, based on generic GTK process, which is that your theme can contain a gimp-dark.css file (additional to the main gimp.css). This secondary file will be used instead of the first when the “Use dark theme variant if available” option is checked in Preferences.

New Default theme in
light and dark variants
New Default theme in light and dark variants - GIMP 2.99.12

File format support


Additionally to the new CMYK support on import, our PSD support got the following improvements:

  • Improved error logging during load.
  • Added support for extra layer mask: according to the specifications the extra mask is used “when both a user mask and a vector mask are present“. We haven’t seen an example that has the extra mask, so not sure which of the masks would appear first. For now assuming that the extra mask will be first. The advantage of adding this here now, is that we won’t try to add a mask channel as a normal channel.
  • Minimal support of duotone data: on import, a duotone image will be imported as grayscale image with an alert and the color information will be stored in a parasite; on export, a dialog will propose you to re-include the duotone data if the image is still grayscale. This allows for a roundtrip in GIMP without losing the duotone information.
New dialogs when importing (left) then re-exporting (right) a PSD duotone image
New dialogs when importing (left) then re-exporting (right) a PSD duotone image - GIMP 2.99.12


Some valid SVG can fail to import when they contain some huge data (of various types). This is not a limitation of the parser but a security limitations, because malicious SVG files can be created on purpose to consume too much memory.

Nevetheless this can still happen on valid and non-malicious files, as some users encounter issues with SVG files exported by Sweet Home 3D (a nice Free Software for drawing interior design plans). Hence when failure to load a SVG occurs, GIMP will propose to try again with the security limitation removed.

Dialog to disable safety limit on failed SVG import
Dialog to disable safety limit on failed SVG import - GIMP 2.99.12

🛈 Note that GIMP doesn’t have the information whether the load failure happened because of this specific issue or not, so if the reason was other, even retrying without security limitation may still fail.

⚠️ Also very IMPORTANT: as explained, this was a safety measure, which implies that disabling it has security implications. You should only accept disabling it to load SVG files from trusted sources, as the pop-up also reminds. ☢️


A new option appeared in the GIF export dialog: “Number of repeats“. It specifies a specific number of repeat for loop animation. Previously you only had the choice of single run animation versus infinite loop.

GIF export dialog
GIF export dialog with new option “Number of repeats” - GIMP 2.99.12


The following changes happened in our PNG support:

  • The format does not have any flag for linear RGB, but it can simply include a linear profile (or a 1.0 gAMA chunk). Therefore since we always attach the profile when importing (or transforming the gAMA chunk into a profile), we now always load PNG images as non-linear backend.
  • When exporting indexed images, a new checkbox “Optimize for smallest possible palette size“, if enabled, will export a PNG file with lowest bit-depth palette possible (less than an 8-bit palette with 256 entries, if possible).


The following changes happened in our DDS support:

  • 16-bit masks now supported.
  • DDS images with single 16-bit channel support added.
  • DDS images with two 16-bit channels correctly converted to 16-bit RGB images.
  • More robust DDS loading.


The following changes happened in our FLI support:

  • 1-frame animation now loaded correctly (it’s not really an animation yet it should still open!).
  • Layer names now include the delay in ms.
  • More robust FLI/FLC loading, double-checking data rather than assuming that the file writer properly followed the specs, better error handling…

Raw data

🛈 We are talking here of “raw data” where you export your pixels as contiguous or planar data directly, without following a specific file format, and not RAW file formats as are usually called formats used by digital cameras (for these, we still prefer to pass through good raw developer software, such as darktable or RawTherapee).

A big rewriting of the Raw Data dialog (and API) organization happened.

First, it is now possible to export any bit depth as raw data (despite the higher bit depth support, exporting 16 or 32-bit images used to still export them 8-bit raw data). This part will also be available in future stable version GIMP 2.10.34.

And especially all exportable formats can be loaded back, and more. As it made for a huge list, the way the import dialog used to list formats, we split settings. Data type (unsigned or signed integer, floating point), endianness or planar configuration (contiguous or planar) are now their own settings and code has been generalized to support each and every combination. The “Pixel format” list is now only about the layout for various components.

Raw data import dialog
Raw data import dialog with more settings and much more support formats - GIMP 2.99.12

As a consequence GIMP now supports a lot more raw data formats, while keeping a usable dialog, without showing a never-ending list of formats.

The PDB API for this plug-in has also been improved to follow the same scheme of separate arguments.

As a last change, the HGT format (supported since the stable version GIMP 2.10.0) is sharing the same codebase so we used to pop the raw data dialog up. Nevertheless we have all the relevant information for a properly formed HGT file, so we now load these directly without dialog (unless we fail to detect the proper sample spacing).

New format: WBMP

GIMP now supports loading WBMP image files, which are monochrome images optimized for the legacy WAP protocol, now mostly discontinued.

The format itself is probably not really useful for new images, but it can always be useful to be able to load existing images from older archives.

Note that this is a limited support as it doesn’t support all features of WBMP, yet hopefully enough to be useful for most use cases.

New format: ANI

GIMP now has import and export support for the ANI animated mouse cursor format.

The export dialog allows you to set hot-spot coordinates for each image in the animation.

Hot-spot coordinates from imported ANI files are stored as parasite in the XCF to be reused as a default when re-exporting.

Export dialog of ANI format
Export dialog of ANI format with cursor name, author, animation delay and hot-spot settings (CC by-sa illustration, shown in-dialog, by Aryeom) - GIMP 2.99.12


Lloyd Konneker, our new Script-fu maintainer, really did take his new responsibility to heart as Script-fu code has not seen such activity for years now.

A lot of bugs were fixed, more documentation for Script-fu developers was written, but also huge changes happened.

Script-fu server now its own plug-in

Script-fu used to be a very monolithic extension plug-in (i.e. a plug-in running permanently in background), with all its features in one binary, which had several drawbacks. One of them is that the Script-fu server (script-fu-server), which allows to communicate with GIMP remotely, would also be running in the same process.

It can be considered a security hazard, which is why it was made its own plug-in, which can be run independently, on request only.

New separate interpreter

GIMP now installs a gimp-script-fu-interpreter-3.0 binary which will run the Script-fu scripts. It has huge advantages:

  • Script-fu scripts are finally proper plug-ins. They are installed within the plug-ins/ folder (not in scripts/ anymore), and work the same way as other bindings. Note that Script-fu is not a GObject-Introspected binding, unlike other bindings, and it has its own way to wrap the PDB protocol or libgimp* libraries, but other than this, it became now much closer conceptually.
  • It makes the Script-fu infrastructure much more robust as a single crashing script will not crash the whole Script-fu altogether. Every Script-fu plug-in now runs in its own dedicated and independant process.

Rethinking the API

Since a lot happened on the main libgimp* API, Script-fu specific API had not been able to follow up. We are now trying to fill that gap and to get Script-fu much closer to the main interface.

Among these changes, the new function script-fu-register-filter is used to declare PDB procedure of the C class GimpImageProcedure. It will also allow to much more easily use the procedural dialog generation through the GimpProcedureDialog class.

A lot of discussions also happened on the topic of argument handling for various types. This is still a work-in-progress as we are trying to improve some use cases, for instance handling of plug-in’s specific lists of options.


The Application Programming Interface for plug-in developer received various improvements and changes within this iteration.

Of course, we have many new functions corresponding to new features in GIMP, such as for the simulation color management, customizable checkerboard colors and more. See the list.

A new gimp_image_metadata_save_filter() also appears, as an alternative to gimp_image_metadata_save_finish() when you want to save metadata yourself and you need only filtering processing. It returns filtered metadata allowing the caller to save the finalized metadata via other means (via native format’s library for example). This API can be used to support metadata saving of image formats not directly supported by gexiv2/exiv2. We already use it for the HEIF/AVIF plug-in.

We also finally got rid of various functions assuming that an image only had a single active layer or channel. We know this is not true anymore in GIMP 3.0, with multi-item selection.

Among the many other changes, one of the most important changes in this updated API is how we handle plug-in localization. While the translation of most strings were left to the plug-in’s discretion, the strings at register time (plug-in title, documentation…) were translated by the core, e.g. when used in menus or in the PDB browser, using gettext catalog given at registration time. This raised various issues, such as what happens if several plug-ins were to register a catalog with the same name (which could have been fixed, with even more complicated internal logic)? Or what happens if a plug-in doesn’t register a localization catalog, but the default catalog contains (wrong) translations for submitted strings? Moreover it ended up to be quite confusing as many plug-in developers were wondering what is translated where, i.e. if a string should be surrounded by _() (common gettext macro) or N_() (noop gettext macro).

So the new logic is much simpler: translation is now left entirely at the plug-in discretion, i.e. all strings received by the core are assumed to be in the correct target language. The core doesn’t try to translate anything coming from plug-ins anymore.

Now to help a bit with localization, our infrastructure proposes a standard file organization, with all gettext catalogs under the locale/ folder of the plug-in directory, and named the same way as the plug-in itself. If the catalog is absent, our system outputs a message on stderr to inform of this standard procedure. A plug-in following this procedure won’t have anything else to do than place the compiled gettext catalogs (*.mo files) with the right domain name in the right folder.

A GimpPlugIn can supplant this behavior at any time by overriding the set_i18n() method, to either disable localization altogether, pointing to a different catalog path and name or even use another system than gettext.

The only remnant of the old logic, which we need to think about and improve, is the localization of menu paths, as we still want core-localization of some base menu paths. E.g. the root menus (“Edit”, “Image”, “Colors”, “Filters”…) but also some submenus (“Blur”, “Enhance”, “Distorts”…) should still be localized by the core while plug-ins will need to handle new parts in the menu path. This is the only exception to the new “no core translation” logic for plug-in.

Batch processing

A new libgimp class GimpBatchProcedure was added, facilitating the creation of batch interpreter plug-ins, i.e. plug-ins meant to be run from command line to process a series of procedure calls. Currently 2 such interpreters exist in GIMP: the Script-fu (plug-in-script-fu-eval) and the Python (python-fu-eval) interpreters.

Running code this way is done with the --batch CLI option. Historically Script-fu was used as default, but this is not the case anymore. Now you must explicitly specify an interpreter with --batch-interpreter.

Moreover a new option --quit was created and this is what you must use if you wish to exit GIMP immediately after the scripts are run. Do not call "(gimp-quit 1)" anymore. A nice improvement is that GIMP will now exit immediately after a batch failure (i.e. if you had a series of --batch calls, it will stop at the first failure) and will propagate the failure into the process exit code. Exit codes are inspired from command Linux error codes: 0 for success, 69 for service unavailable (e.g. setting a non-existing interpreter name), 64 for usage (e.g. not specifying any interpreter or calling errors), 70 for execution errors (bugs in the interpreter plug-in) and 130 for canceling the call. Therefore you will now know when your scripts fail.

As an example of batch processing, here is how you could load a PNG image, then export it back as JPEG:

$ gimp-2.99 --batch-interpreter python-fu-eval -idf -b "img=Gimp.list_images()[0];layers=img.list_layers();c=Gimp.get_pdb().lookup_procedure('file-jpeg-save').create_config();c.set_property('image',img);c.set_property('file',Gio.file_new_for_path('/home/jehan/out.jpg'));c.set_property('drawables',, layers, False));c.set_property('num-drawables',len(layers));Gimp.get_pdb().run_procedure_config('file-jpeg-save',c)" --quit  /home/jehan/in.png

This long command line may seem frightening, but this is the same script in a file, named for instance

img = Gimp.list_images()[0]
layers = img.list_layers()
c = Gimp.get_pdb().lookup_procedure('file-jpeg-save').create_config()
c.set_property('image', img)
c.set_property('file', Gio.file_new_for_path('/home/jehan/out.jpg'))
c.set_property('drawables',, layers, False))
c.set_property('num-drawables', len(layers))
Gimp.get_pdb().run_procedure_config('file-jpeg-save', c)

Run it through GIMP in batch mode like this:

gimp-2.99 --batch-interpreter python-fu-eval -idf -b - --quit  /home/jehan/in.png <

Of course, you can add in your scripts any filtering or image manipulation, through GEGL or libgimp API.

Build and documentation

meson (message to packagers)

GIMP build system traditionally uses GNU autotools. An initial, yet incomplete, port to the newer meson system was contributed in 2017 by Félix Piédallu.

It took a few years to complete the last customizations, tweaking meson scripts to be able to handle all the special cases we had in GIMP code. As we approached completion in this development cycle, we started to officially recommend meson for Windows, then macOS, and finally, early August, we decided to recommend meson for all platforms.

This is still an evaluation phase for this build system, though now we are moving forward into intensive testing. If you are a packager, please try to now use our meson build and report any issue to us.

Exceptionally for this version, we released 2 tarballs on our download server: gimp-2.99.12.tar.xz and gimp-2.99.12-autotools.tar.bz2. As you can guess, the former is the meson-generated tarball, yet we left an autotools-generated tarball as fallback if the meson tarball end up having major issues.

The INSTALL file was rewritten as well with meson instructions.

Of course, all our own packages (flatpak for Linux, installer for Windows and DMG for macOS) are now built with meson.


As many other projects, GIMP was using the intltool project to extract localizable strings and translate various files with gettext, not only code.

Since about 2016, upstream gettext gained the ability to extract strings for more types of files and formats, projects were encouraged to move on and the intltool project was progressively abandoned. But GIMP was still using it for various types of files (XML, desktop files, Inno Setup translation files and more…) so the workfield was not small.

Well no more as Niels De Graef finally took care of this port and got rid of this technical debt! 🥳

Of course, it triggered various problems, even to release day as we realized when testing installers that some buttons were broken (which is one of the few reasons why this news is out days after the actual source release) and we had to fix the strings. Hopefully this was the last related issue!

Platform support


Wayland issues are slowly yet surely being getting rid of. Some of the issues we had just disappeared with more recent versions of some Wayland compositors. We do hope more bugs in upstream compositors will be fixed eventually because some serious issues are still puzzling us (such as crashes of some GTK applications, GIMP included, on the Sway Wayland compositor).

Some other issues have been handled in our code.

One of them is that early testers may have noticed a very annoying popup telling you that “gimp-2.99 wants to inhibit shortcuts” (at least on Mutter, the Wayland compositor of GNOME) in former 2.99 versions. This got fixed by removing various keyboard grabbing code which was not necessary anymore with GTK+3.0.

Some issues still remain, based on the early state of Wayland in general, in particular because it doesn’t have color management. We were often advised to use the “portals” for various features, such as color picking, which unfortunately do not return us color-managed colors (as a side issue, some desktop — such as Cinnamon and Mate — simply are missing implementation for the color picking portal even though the portal exists, which confuses GIMP). This is a regression problem because we were getting wrong colors (slightly wrong, or even very wrong if you use a wide gamut display) even when one were still running on X11. Therefore now we will favour the X11 implementation for color picking when you are running on X11 and will use the portals only on Wayland. We may go back to portals for everyone on Linux when they return managed colors.

Meanwhile, we are in discussions with Freedesktop portal developers to get a new color-picking portal API, which will eventually have to be implemented for the various desktops. Let’s hope it happens sooner rather than later! 😅


As usual, a lot of maintenance work was done by Lukas Oberhuber. Packaging work is not as visible, hence is quite often thankless, which should be fixed: thanks Lukas as well as every other packager!

Apart from this, you may remember the slowness issues happening on newer macOS versions (ever since Big Sur). We had some custom patches already for GTK and some dirty trick in GIMP code itself since GIMP 2.99.10.

It all led to various improvements in GTK code which took over the previous patches. It took months of testing, several code proposals in several directions (at least 3 different merge requests, possibly more code was discarded) and it got to a very satisfying result as Lukas confirmed it is much faster now and GIMP is totally usable. Our in-GIMP dirty tricks could also be removed. For all these improvements, we want to thank in particular John Ralls who provided the final fixes and Christian Hergert for his constant inputs. Of course, we should not forget the numerous other contributors who stopped by to help and give useful inputs. Hopefully GTK on macOS will continue to improve even more!

In any case, this is great news for all other multi-platform GTK software, though no GTK+3 release contains these fixes yet. It will be available in GTK+ 3.24.35.

We include a patch on Cairo (again by John Ralls) as well for improved performance on macOS, though the gained performance was not as obvious as the GTK fix.

Also additionally to the development releases, we now provide nightly builds for macOS. Check the section “Automatic development builds” of the Development download page for a procedure. ⚠️ As usual, we remind that nightly builds means that it’s even more experimental than development builds: these packages happen at random point in the development process and the builds are not even human-tested. ☢

In any case, a lot has happened since the days, not so long ago, when we were despairing at the sad state of GIMP on macOS, with slowness (to the point of being unusable) and interface issues. Now we are finally getting to a point where we can hope GIMP 3.0 will be great on macOS, though we are still very short on contributors for this OS. We welcome any developer wanting to join us!

Last point for people waiting for M1 builds: some work has been done in this direction, but we are mostly blocked by CI hardware limitations. We’ll keep you updated on improvements for this topic obviously.

For people who have a M1 Mac and are willing to build locally, there are build scripts, in the gimp-macos-build repository though starting from the README might be ideal. Note that Lukas is already doing all his work on M1 machines now, so we are just waiting for CI support to provide proper packages.

babl and GEGL

As usual, this release is supplemented with the releases of babl 0.1.94/0.1.96 and GEGL 0.4.38.

babl 0.1.94/0.1.96

babl 0.1.94 fixes a crash on non-aligned data for SIMD and improve vala compatibility of introspection information.

It also brings a new command line utility for converting unique colors from one format and/or space to another. This is very useful to us for testing our color conversions and verifying that GIMP code does the right conversions too, which is why we wrote this tool in the context of the color invasion project.

For instance, to convert some color from sRGB to the CIELAB color space:

$ babl -f "R'G'B' u8" -t 'CIE Lab float' 100 100 100
Converting from "R'G'B' u8" to "CIE Lab float":
- 42.374615
- 0.000000
- 0.000009

Usage is:

$ babl --help
Usage: babl [options] [c1 ..]
Convert color data from a specific Babl format and space to another.

     -h, --help            this help information

     -f, --from            input Babl format

     -t, --to              output Babl format

     -i, --input-profile   input profile

     -o, --output-profile  output profile

     -r, --intent          rendering intent
                           it only works with an output profile

     -b, --brief           brief output
                           it can be re-entered as input for chain conversions

All parameters following -- are considered components values. This is useful to input negative components.

The tool expects exactly the number of components expected by your input format.

The default input and output formats are "R'G'B' float" and default space is sRGB for RGB formats, or the naive CMYK space for CMYK formats.

Of course, this tool is still meant to evolve.

Note that babl 0.1.96 is functionally the same as babl 0.1.94, except for a fix in the build system, which was preventing to build babl from a tarball. Packagers in particular should therefore use the latest version.

GEGL 0.4.38

A new denoising operation called “Denoise DCT” ("denoise-dct") was introduced by Thomas Manni. It decomposes the input buffer to sliding overlapping patches, calculates the DCT denoising in each patch, and then aggregates the denoised patches to the output buffer averaging the overlapped pixels.

As for existing operations, the following were improved:

  • ff-load and ff-save: big API cleanup, now ffmpeg-5.0 compatible.
  • gif-load: updated to latest upstream libnsgif version.
  • slic: progress reporting and improved parameter handling.
  • vector-fill: updated to latest upstream ctx version.
  • oilify: clamp inputs to avoid nan in output.
  • gegl:load: fix possible double free.
  • rgbe-write: plug leaks in error paths.

Apart from bug fixes, other interesting points are that the build simplified using GEGL as a subproject and the continuous integration has been rewritten to be more reliable.

Team news

Aryeom got reporter access to gimp and gimp-web to help with various design-related issues.

Daniel Novomeský, maintainer of our JPEG-XL and HEIF/AVIF plug-ins, has been given access right to our flathub repository (for our stable and development flatpak) to help with maintenance.

We’d like to thank a category of contributors who are historically not much in the light: release testers. Recently in particular, as we are enhancing our continuous integration and release process, we also try to improve manual verifications before release. Users are very welcome to discuss with us and hang out on our discussion channels during release frenzy to test the final builds.

For our Windows installer, additionally to packagers (Jernej Simončič) and developers (Jacob Boerema), we want to thank Sevenix for having always been on-call, testing our installers for a few releases now. Sevenix also helps us to moderate our recent Discord discussion channel.

This is true for the Linux flatpak and the macOS DMG as well, as in these case, only their packagers (respectively Jehan and Lukas Oberhuber) have been testing them before release these days. So whatever is your platform of choice, please join us!

It’s a good reminder that you don’t need to be a developer to contribute back. There are tasks for designers, packagers, testers, translators, documenters and more! 🤗


Documentation website

We regularly write about this here: the new maintainer of the gimp-help repository (our documentation), Jacob Boerema, has been improving it for over a year now, doing much needed maintenance, removing technical debt, and improving what existed. But you could not see much of it… until today!

Indeed he very recently updated the online documentation website. As you can see, from the landing page already, we finally see all languages, and each of them show their translation ratio now. We do hope it will trigger more people to help and contribute to translation! 😸

A daily-update process has also been set up, so that we won’t ever get back in this bad situation of outdated online documentation for years (even though some contents were already fixed in-repository).

The Quick Reference PDF is now also available in every supported language (once again with translation completion percentage showing up).

Of course, a lot of original contents still deserve more love, either outdated, or information about new features may be missing. There is just so much that a man alone can do. Yet now the infrastructure is there to welcome a much faster update and feedback process, so if anyone wants to contribute to the documentation, you should look at the repository and propose merge requests. The contribution format is DocBook.

For translation contributions, you should get in touch with GNOME translation teams as they have their own platform. More information is available here.

A dedicated news with more details might soon be published, possibly if we decide to make a new tagged release of the manual, which will mean new installers for Windows, and tarballs for other platforms and for packagers, containing up-to-date contents for offline usage.

Development website

Meanwhile our developer website was in an even more dire situation as it had not been updated for over 10 years!

This is about to change as one of our goals for GIMP 3.0 is to improve the plug-in ecosystem, not only with an upcoming extension platform, but also with better and more up-to-date documentation.

The work on the new developer website is finally starting, thanks to the impulsion by Robin Swift, a new contributor, and help from Pat David (who is the long-time contributor who already helped by revamping our website and created the PIXLS.US community for FLOSS photography tool).

We already ported the website contents, away from DocBook, to the Hugo platform. This should simplify contributions. We also cleaned most of the outdated contents and started to port some contents which were stored in the source repository itself and from the wiki.

Ah, the wiki! Some people might have noticed that it is gone now. We used to have the roadmap, build instructions for newcomers and more technical or historical stuff over there. Let’s say that unfortunate events occurred and we lost it. 😱

Fortunately all the contents could be salvaged, and we plan to port the valuable parts into the upcoming developer website, nicely organized. After all, both the wiki and the developer website were filling a similar purpose (with the exception that one was mostly abandoned). So in the end, it’s a good thing, organization wise, right? 😅).

It’s still very early in the migration process, so we will keep you up-to-date with more exciting news soon.

Mirror news

A new mirror joined us to distribute GIMP.

Thanks to SandyRiver.NET in Pikeville, Kentucky USA, for sharing the download load!

Book news

Three German books and three Polish books about GIMP have been added to the books page:

We remind that we welcome book additions. Whether you wrote it or just read it, if you know of a book about GIMP, just report the same information as other books in the list. Thanks!

Release stats

61 people contributed to the main repository for GIMP 2.99.12:

  • 23 developers contributed to GIMP code base for this micro version:
    • 1 developer with more than 300 commits: Jehan.
    • 4 developers with 10 to 50 commits: Jacob Boerema, Nikc, Loyd Konneker, Niels De Graef.
    • 18 developers with less than 10 commits: Povilas Kanapickas, Kevin Cozens, Lukas Oberhuber, woob, Simon Budig, Anders Jonsson, Axel Viala, Ben Rogalski, Claude Paroz, Daniel Novomeský, GokhanKabar, Jan Tojnar, L amander, azetoy, houda, Øyvind Kolås, ktoyle and Sonia Habtiche.
  • 25 translations were updated: Basque, Brazilian Portuguese, Bulgarian, Catalan, Chinese (China), Danish, Dutch, Finnish, French, Galician, Georgian, German, Greek, Hungarian, Icelandic, Korean, Persian, Polish, Portuguese, Russian, Slovenian, Spanish, Swedish, Turkish, Ukrainian.
  • 35 translators contributed: Yuri Chornoivan, Hugo Carvalho, Martin, Rodrigo Lledó, Zurab Kargareteli, Luming Zh, Anders Jonsson, Fran Dieguez, Sveinn í Felli, Nathan Follens, Asier Sarasua Garmendia, Balázs Úr, Matej Urbančič, Alan Mortensen, Aleksandr Melman, Alexandre Prokoudine, Claude Paroz, Jordi Mas, Sabri Ünal, Balázs Meskó, MohammadSaleh Kamyab, Alexander Shopov, Jiri Grönroos, Piotr Drąg, dimspingos, Charles Monzat, Hannie Dumoleyn, Jürgen Benvenuti, Tim Sabsch, Alexandre Franke, Aryeom, Boyuan Yang, Danial Behzadi, Maíra Canal and Rafael Fontenelle.
  • 4 people helped with in-code documentation: Jehan, Lloyd Konneker, Niels De Graef and Akkana Peck.
  • 1 person contributed to icons: Stanislav Grinkov.
  • 3 people contributed to cursors: Aryeom, Jehan and L amander.
  • 3 people contributed to themes: Jehan, Akkana Peck and Nikc.
  • 12 people contributed build-related updates: Jehan, Lloyd Konneker, Akkana Peck, Anders Jonsson, Jan Tojnar, ktoyle, Øyvind Kolås, Lukas Oberhuber, Bartłomiej Piotrowski, Ondřej Míchal, Daniel Novomeský and Jacob Boerema.

These are the stats on babl, GEGL and ctx repositories:

  • 7 contributors to babl 0.1.94 and 0.1.96:
    • 3 contributors with multiple commits: Axel Viala, Øyvind Kolås and Jehan.
    • 4 contributors with single commits: Eli Schwartz, Lukas Oberhuber, Sergey Torokhov and Xavier Claessens.
  • 24 contributors to GEGL 0.4.38:
    • 7 contributors with multiple commits: Øyvind Kolås, Behnam Momeni, Thomas Manni, Michael Drake, Xavier Claessens, Axel Viala and Anders Jonsson,
    • 3 contributors with single commit: Felix Schwarz, Jehan and darnuria.
    • 15 translators: Hugo Carvalho, Piotr Drąg, Rodrigo Lledó, Yuri Chornoivan, Anders Jonsson, Luming Zh, Martin, Zurab Kargareteli, dimspingos, Alan Mortensen, Jordi Mas, Marcia van den Hout, Marco Ciampa, Sabri Ünal and Tim Sabsch.
  • ctx doesn’t have releases per-se as it is project-embedded code. So let’s count commits in the time frame between GIMP 2.99.10 and 2.99.12:
    • 1 contributor with 396 commits: Øyvind Kolås.

On the documentation repository, in the same time frame as GIMP 2.99.12, 26 people contributed:

  • 1 contributor with more than a hundred commits on documentation and scripts: Jacob Boerema.
  • 7 contributors on the documentation itself or scripts, with less than 30 commits: Jehan, Anders Jonsson, Andre Klapper, Balázs Úr, Daniele Forsi, Jernej Simončič and Marco Ciampa.
  • 21 translators: Rodrigo Lledó, Jordi Mas, Nathan Follens, Yuri Chornoivan, Marco Ciampa, Anders Jonsson, Tim Sabsch, Hugo Carvalho, Balázs Úr, dimspingos, Alan Mortensen, Aleksandr Melman, Charles Monzat, Claude Paroz, Danial Behzadi, Kjartan Maraas, Luming Zh, Martin, Matheus Barbosa, Milo Ivir and Ulf-D. Ehlert.

On the main website repository:

  • 1 contributor contributed 76 commits: Jehan.
  • 5 contributors contributed 1 to 10 commits: Alexandre Prokoudine, Anders Jonsson, Tom Gooding, Alberto Garcia Briz and Babs Keeley.

On the macOS build repository:

  • 1 contributor contributed 71 commits: Lukas Oberhuber.
  • 1 contributor contributed 2 commits: Jehan.

On the developer website repository:

  • 3 contributors: Jehan, Pat David and Robin Swift.

Note: considering the number of parts in GIMP and around, and how we get statistics through git scripting and manual tweaking, errors may slip inside these stats. Feel free to tell us if we missed or mis-categorized some contributors or contributions because we try to acknowledge every contributor for being a part of GIMP!

Downloading GIMP 2.99.12

As usual, GIMP 2.99.12 is available on GIMP official website ( in 3 package formats:

  • Linux development flatpak
  • Windows installer
  • macOS DMG package

Other packages made by third-party are obviously expected to follow (Linux, *BSD distributions’ packages, etc.). The MSYS2 project is also apparently planning to package the development version soon too.

What’s next

This release is once again a major milestone towards GIMP 3.0. All 2.99 development versions were big milestones, but we are really feeling we are getting close to release candidates now, with some great improvements happening in much needed places:

  • we are finally getting proper neutral-gray themes;
  • our Wayland build is finally getting a bit stabler (even though issues remain);
  • our macOS build is really on the usable side now;
  • our last remaining GTK port issues are slowly, but very surely, getting taken care care of;
  • the space invasion project is showing leaps thanks to the CMYK project (which forces us to review color space issues as a whole);
  • Script-fu and the API in general are getting much love;
  • several of our long-worked improvement projects are getting to an end;
  • and more as so many things are on the work!

We still can’t give you any date for GIMP 3.0, but we are getting there! 🤩

Don’t forget you can donate and personally fund GIMP developers, as a way to give back and accelerate the development of GIMP. The maintainers of GEGL and GIMP are crowdfunding to be able to work full-time on free software, which could happen thanks to its community! 💪🥳