Hello there!
(Warning: this post is mainly intended for script writers, it talks about technical stuffs about G’MIC-scripting).
I’d want to share some news about the evolution of the G’MIC scripting language here, with the apparition of two new native commands: store
and restore
(native means they are hardcoded in the G’MIC interpreter, so they will be available only in the next release 2.7.2 of G’MIC).
This addition comes from a thought I had after reading the question from @Reptorian on copying images in variables. These new native commands are basically a faster implementation of the img2var
and var2img
commands I’ve just introduced in the stdlib
yesterday, as an aswer to @Reptorian’s request.
Let me quickly describe how these new commands works:
Command store[selection]
takes a selection of the images in the current list, and transfer them to a binary-encoded variable (transfer meaning that after the call to store
, the images are not present in the list anymore. But of course, to keep them available, you can use +store
instead).
Command restore
does almost the opposite : it inputs the content of such a image-based variable at the end of the image list (but it does not reset the variable content, so it’s more like getting a copy of the images stored in the variable).
The good thing is that this pair of commands relies on the same variable mechanism we had before in G’MIC, meaning the same rules apply for these image-valued variables (e.g., such variables are still local to a command, unless the variable names start with an underscore).
For instance, you can do things like:
foo :
sample lena,landscape
store[0,1] two_images # Store 2 images in variable named 'two_images'
if narg($two_images) # Test if variable has been assigned
two_images="" # Empty variable to free stored image buffer
fi
sample bottles,eagle
store[0,1] two_images # Store 2 different images in variable 'two_images'
(...) # Do what you want here
remove # Empty image list
restore two_images # -> Restore the two images, by inserting them at the end of the image list.
two_images={2*pi} # Re-use variable 'two_images' to store a string
So, as you see, store
and restore
are just helpers to assign/access image-based content to a variable (from now, only text strings were supported for assigning variable values).
Why do we need that in G’MIC ?
Well, one use case it the following : suppose you have to write a command with an image as an argument, and do something on your selection with that argument image (e.g. blend all images of the selection with the argument image).
Then, previously, you would have written something like:
#@cli foo1 : [image]
#@cli : Alpha-blend all selected images with the specified image argument.
foo1 : check ${"is_image_arg $1"}
pass$1 0 to_rgba. # Insert argument image at the end of the list
repeat $!-1 l[$>,-1] # Loop over image selection, and keep last image for computing the blending
+blend alpha # Compute blending
reverse remove. # Keep the 2 images in the local environment as a result
endl done
remove. # Remove argument image that has been inserted with `pass`
The example above is not really complicated, but still, you see it requires you carefully manage the image list, as you have inserted an additional ‘argument’ image in the list.
Now, with store
and restore
, a similar command can be written as:
#@cli foo2 : [image]
#@cli : Alpha-blend all selected images with the specified image argument.
foo2 : check ${"is_image_arg $1"}
pass$1 0 to_rgba. store. arg_img # Store argument image in variable '$arg_img'.
repeat $! l[$>] # (Classical) loop over image selection,
restore arg_img # Input argument image in local environment
blend alpha # Compute blending, which ends up with a single image in local env
endl done
This doesn’t make a difference in the number of lines to write, but believe me, the second version is really easier to write !
There are still work to be done on this. Even if most of it is already functional, some things are not working as expected (in particular, the copy operator between variables arg_img2=$arg_img1
does not work right now, and it will be a bit tricky to implement. But I’ll try to do it !