Release of G'MIC 2.9

This is the changelog for the release of the 2.9.x versions of the G’MIC software.
It lists all new features and changes done since the latest version 2.8.4.

What is G’MIC?

G’MIC (GREYC’s Magic for Image Computing) is a full-featured open-source framework for image processing. It provides several different user interfaces to convert/manipulate/filter/visualize generic image datasets, ranging from 1D scalar signals to 3D+t sequences of multi-spectral volumetric images, thus including 2D color images.


^ The plug-in G’MIC-Qt in action, running for GIMP 2.10 ^

What’s new in version 2.9.x?

New features:

  • [gmic-qt_290] New filter Rendering / Tree renders a fractal tree, with various parameters that can be tuned to generate different kind of trees.

  • [gmic-qt_290] New filter Sequences / Moiré Animation produces still images that can be animated with a transparent sheet, from several frames (layers), as shown in the video

  • [gmic-qt_290] Filter parameter color() now accepts an argument that is a RGB or RGBA colors in HTML format (e.g. #aabbcd or #aabbccddee).

  • [math_core_290] New functions maxabs(), minabs(), argmaxabs() and argminabs() find the min/max (in absolute value) of a list of arguments. New commands maxabs, minabs, argmaxabs and argminabs also added to operate on image pipelines.

  • [math_core_290] New functions name(_#ind,_siz) and setname(_#ind,str) get/set the name of an image of the list (eq. to command name but directly inside the math parser).

  • [math_core_290] New function ref(expr,varname) references the specified expression expr by the variable varname. Useful to declare large vector-valued variables while avoiding memory duplication in the math parser (e.g. ref(vector1024(),A) is better than A = vector1024(), as the latter requires two allocations and a call to the vector copy constructor).

  • [math_core_290] New function lerp(a,b,t) computes the linear interpolation between arguments a and b (i.e. a*(1-t) + b*t).

  • [math_core_290] New function inrange(val,a,b,include_boundaries) tests if a value lies in a given range.

  • [core_290] Most substituting expressions between braces {} can now specify a delimiter option, that delimits multiple values coming from a substitution (e.g. {[1,2,3]:;} is substituted as 1;2;3 and {'foo:^} by 102^111^111). Accepted delimiters are , (default), ;, /, ^ and ’ ’ (space).

  • [core_290] New input expressions ('string') and ('string':delimiter) now available, to create images containing the character codes composing the string (equivalent to ({'string'}) and ({'string':delimiter}) where delimiter can be , (default), ;, / or ^). For this special expression, delimiter can also be specified as x,y,z or v to set the main image orientation.

  • [stdlib_290] New command parse_gui parses all #@gui filters available (e.g. all filters defined for the G’MIC-Qt plug-in) and outputs filter information in a format following a given output mode (json | list | print | update | zart).

  • [stdlib_290] New commands input_text (shortcut it) and output_text (shortcut ot) load/save text-data files as new images containing the ASCII characters as unsigned char-valued pixels (eq. to using expression raw:filename.txt,uchar).

  • [stdlib_290] New command strcapitalize capitalizes an input string.

Modifications / Improvements:

  • [gmic-qt_290] G’MIC now supports UTF-8 encoded command files. All existing command files have been converted to UTF-8. In scripts, strings can also specify UTF-8 characters with the \u or \U prefixes (as in "\uA0B3" (ꂳ)). Note that UTF-8 characters are still not rendered by command text.

  • [gmic-qt_290] Enable link-time optimization (flag -flto) when compiling the CLI tool on Linux. This produces a binary with an improvement of 14% in size.

  • [cli_290] Command help has been redesigned, and always outputs help messages on stdout.

  • [core_290] Command discard has been optimized when called with a single scalar argument.

  • [core_290] Command display now outputs info on console for verbosity>=0 (was >=1 before).

  • [core_290] Loading animated .gif now always returns full frames (rather than difference frames).

  • [core_290] Command store accepts an optional argument is_compressed that tells if stored images must be stored in a compressed form.

  • [math_core_290] Function find() is now able to search inside a vector with a given step (positive or negative).

  • [math_core_290] Function store() can now store a sub-vector as an image-valued variable.

  • [stdlib_290] Commands version now always output messages on stdout.

  • [stdlib_290] Command compress_gmic has been recoded and is now faster to execute.

  • [stdlib_290] Interactive viewer for 2D images now accepts shortcut CTRL+W to close the window.

  • [stdlib_290] Command echo (shorcut e) can be invoked as +echo[] (shortcut +e[]) to output on stdout rather than stderr (equivalent to echo_stdout).

  • [stdlib_290] Command colormap has been optimized for extracting all existing colors from an input image (with argument 0).

  • [stdlib_290] Command display2d is now able to perform multi-image display with synchronized views, when selected 2D input images are stacked along the z-axis. Command display_parallel enables this mode by default when compatible images are displayed.

Bug fixes:

  • [core_290] Value of milliseconds timer $| was resetting itself each day, on Windows. This is now fixed. Precision of the timer has been also improved when running after several days.

  • [core_290] Command fft: Fix calculation of FFT along ‘y’-axis when used with volumetric images.

  • [core_290] Fix substituting expression {ind,b} when image name is empty.

  • [core_290] Expressions s.a. .,.,.,.xN are now recognized.

  • [core_290] Fix bug in thread waiting functions (wait_threads() is now thread-safe).

  • [math_core_290] Check constant image index, when accessing vector-valued expressionsI/J[#ind,off] and I/J(#ind,x,y,z,c).

  • [gmic-qt_290] Fix critical bug in filter Montage (regression introduced in 2.8.4).

  • And a lot of other small bugfixes!


Thank you!
I am very keen of this parser that I will use very soon for GitHub - myselfhimself/gmic-blender: Official G'MIC plugin for Blender3D - pre-pre-alpha :slight_smile:

By the way a minor typo in gmic_stdlib.gmic oneliner_lightspeed instead of onliner_lightspeed!

Concerning :
If I make a completion script with ‘make bashcompletion’ I have to comment several lines at the beginning and the end for functioning completion under zsh!

local cur prev opts coms 

# if type -t _init_completion >/dev/null; then
# _init_completion -n = || return
# else


COMPREPLY=( $(compgen -W "$opts" -- "$cur") ) 

# if type -t _filedir >/dev/null; then
# _filedir
# else
# comptopt -o filenames 2>/dev/null
# COMPREPLY=( (compgen -f -- {cur}) )
# fi
complete -F _gmic -o filenames gmic

I have some problem with the latest develop gmic cli build:

gmic osteo +inrange 25,190
[gmic]-0./ Start G’MIC interpreter.
[gmic]-0./ Load osteoblast nucleus example image
[gmic]-1./ Detect pixel values in range [25,190] in image [0], with boundaries included.
[gmic] *** Error in ./inrange/_inrange/*repeat/*local/ *** Command ‘fill’: Unrecognized function call ‘inrange(i,25,190,1)’ in expression ‘inrange(i,25,190,1)’.
[gmic] Command ‘fill’ has the following description:

fill (+):
    value1,_value2,... |
    [image] |

Need recompilation, inrange() is a new math function that has been introduced recently in the math parser.

Hmm, I did it at
-rwxr-xr-x 1 karo staff 6435616 11. Mär 12:52 /usr/local/bin/gmic*

Are you sure this is the latest sources ? (branch develop ?).
It works here for me. I don’t see why it couldn’t work for Mac Users, there is nothing Mac specific.

See, perhaps with git something wrong

/Users/karo $ (cd work/src/gmic; git branch -a;git pull)


ll /usr/local/bin/gmic

-rwxr-xr-x 1 karo staff 6435616 11. Mär 13:31 /usr/local/bin/gmic*

and my build command

(cd ~/work/src/gmic/src/; make -B cli “SUBLIBS=-lX11” || exit; sudo cp ~/work/src/gmic/src/gmic /usr/local/bin/)

ha but did you try make clean before compiling ?
It requires CImg.h to be updated !

No, i’ll try

Normally I do

(cd ~/work/src/gmic ; git pull ; grep “#define gmic_version” ~/work/src/gmic/src/gmic.h | tail -c 17) ; (cd ~/work/src/CImg ; echo CImg ; git pull) ; (cd ~/work/src/gmic-qt ; echo gmic-qt ; git pull) ; (cd ~/work/src/zart ; echo zart ; git pull) ; (cd ~/work/src/gmic-community ; echo gmic-community ; git pull) ; (cd ~/work/src/gmic_bm ; echo gmic_bm ; git pull) ; echo “gmic version up”; gmic version up; echo “kgmic version up” ; /usr/local/bin/gmic version up

That is not sufficient, additionally make clean?

The problem is that CImg /gmic are right now in v.2.9.0_pre, with gmic_version being 290, but with new features added regularly.

Ok, I am not on develop branch in CImg! Hope that helps.

Normally I am not so interested to be too near to your progress. It was by chance that I used some thresholding!

It’s now ok with gmic and CImg in develop branch!

Thanks for the hints!

Still some (minor?) problem

gmic osteo +median 13 +sub +ir. 5,20 +ir… -20,-5

[gmic] *** Error in ./ir/_inrange/*substitute/ *** Unknown command or filename ‘s-5’ (did you mean ‘-’ ?).

still gmic osteo +median 13 +sub +ir. 5,20 +f[-2] inrange(i,-20,-5,1) does the job.

Confirmed, and fixed. Update will be ready in a few minutes.

I’ve just posted new pre-release binaries for 2.9.0_pre, on the pre-release page : Index of /files/prerelease
(for most of the supported OS/distros).

It looks like it is almost ready for a stable release. If you feel like a beta tester, don’t hesitate to install it and give me feedback if you encounter any problem!

Merci les amis.


I don’t see lerp(a,b,t) working in fill. I’m not sure if that was supposed to be there, so. It’s not that hard to create a macro of it within fill though.

Works for me. Have you updated to the latest binary? pre has been rebuilt a few times. Kind of confusing I know because the name is the same.

Yeah, it works. I was expecting that update works fine through gmic update, but it seems I had to do hard update.

update only applies to non-core elements; i.e., stdlib and community. Features inherited from cimg require a new binary. If I knew C++ (or could learn it) I would write everything for CImg since it would make operations much faster.