The Big Bad G'MIC Thread of Silly Questions

eval… I wish could say “yeah, i’ll try that!” but i have no clue where to begin.

I mean, this grass is made with 2 nested do ... while statements.
Trying to find an example now.

Yes, probably lol.
THen, on this matter, i always wondered if there was any difference between parallel and apply_parallel.

is it :
ap: apply same command(s) to all (selected) images in the list
parallel : apply different command(s) to different images (command1[0] , command2[1], etc) in… parallel

?

Yes, apply_parallel apply the same command to its selection, e.g:

$ gmic sp lena,cat,tiger apply_parallel[0,2] \"flower 30\"

It does the same as flower 30 but in parallel (could be interesting if you have a lot of images, e.g. you want to apply a command on 100+ images).

On the other hand, parallel let you run different commands in parallel, as in:

$ gmic sp lena,cat,tiger parallel \"flower[0] 30\",\"blur[2] 20\"

you should always run different commands on different images, to be sure no concurrent threads are trying to modify the same image (which could lead to crash).

Yes, already tried that a long time ago :slight_smile: Nice way to create a smoke effect with g’mic, if you see what i mean.

Ok, didn’t use eval, but got it running under 1 second.
When i started this grass i was using units in px, then changed to %. I still had my loops checking x or y against w or h, so that was translated as 1500% or 700%.
do ... while $X<=w
Switched that back to 100%, that’s better, right?
do ... while $X<=100

Still not happy with the look but at least i don’t have to wait to check the horror.

What is the right way to use ja to combine RGB + alpha? I could useblend alpha` but i have images of different sizes, so “ja” is more convenient for placement than expanding images to the right size (as this can eat more ram).
Looks like i always have to do 2-3 more operations just to use alpha correctly. I’m probably doing it wrong.

gmic run 'shape_cupid , shape_rays , n 0,255 to_rgb s c i[3] [2] [-1] a[0-3] c a[1--1] c +ja.. . d0 s. c d0 '


Pasting rays on top of cupid but they don’t appear

Uh Oh there they are but Alpha-chan is sad because she doesn’t have rays like cupid

It looks like the selected image for ja (background image) must be RGB, not RGBA.
I’ll check what happens.

OK, so a word about ja (aka imagealpha). It works quite differently from blend alpha:

ja actually assumes that the last channel of the image specified as the argument is an alpha channel. Then if you argument image has N channels, it just draws the N-1 channels over the selected images, using the last channel as a transparency mask. It does nothing more fancy than that.

So if you want to draw over a 4 channels image (e.g RGBA image), you should specify a 5-channels image as the argument to ja.
But, command ja does not care about the “meaning” of the last channel of the selected image. It just says “the last channel of the argument image is an alpha-channel”.
So if your selected image is a CMYK image, and your argument image is a CMYKA image, it works as it should.

It’s very different from what blend alpha does, because the alpha blending command assumes that if either the background or foreground image has 4 channels, it’s RGBA
(e.g. you cannot use blend alpha to blend two CMYKA images).
And alpha blending between a background image that has an alpha channel, and a foreground image that also has an alpha channel is not as simple as drawing a N-channels image over an N-channels images (particularly because alpha channels mix together in alpha blending, with specific equations).

Alright, so i guess that for me it will be :

RGBA on RGB = ja
RGBA on RGBA = blend

And you could add arbitrary channel selection or all of them, _blend_$mode here.

I’m not sure what you mean actually…
This could be something I do without putting words on it, or something I don’t know.

Blend command use subcommands _blend_* in which you can take advantage of to use in case of 5+ channels or individual channels.

Note: * can be name of blending mode.

Also applies to alpha too.

Ok… :laughing: i’m really starting to think that g’mic commands are built upon this model :

Yes. As are many things within and outside G’MIC, the design pattern in play is that of taking so many axiomatic things, typically small and concrete, and constructing larger scale, more generally applicable, abstractions. “The building is made of bricks. The bricks are made of…” Regarding that, the G’MIC core built_ins are axiomatic, implemented in C++, and constitute the inner-most “dolls”.

What is often overlooked in G’MIC is the profound significance of the : operator, which sets the left hand key to represent the right hand pipeline template. See Basics. That lowly operator furnishes the basis of constructing custom commands, the larger “dolls”, which further lend themselves as right-hand components of other, larger scaled “dolls” further defined through the use of the : operator. And so it goes. There is no cap to this.

It can take one’s breath away to recall that the only image processing work that ever gets done in G’MIC is through the built-ins — that all custom commands are, in a sense, root nodes of directed acyclic graphs, these serving as mechanisms solely for the purpose of choosing and sequencing collections of built-in commands. We could, in principle, write pipelines solely with built-ins, serving some god of efficiency, perhaps. Such endeavors are exasperating by their nature. We need the clumping mechanism of the : operator to express shorthand consolidations what could otherwise be vast networks of built-in commands.

You’re probably at the stage where you should break open gmic_stdlib.gmic and start to make sense of it. One can only go so far in accepting custom commands as convenient black boxes. They are, but insight arises from understanding what they are.

That’s beautifully said. Reading this, I could almost feel like I’ve done something clever! :stuck_out_tongue:

Being down to earth, I can tell you that 64 is the max number of nested command calls. So there is a cap.

I’m in a teasing mood today!

Curious: has anyone ever run into this cap?

No. But, it isn’t hard to do it. Just make a repeat and use command command, and you’d hit the cap.

I don’t see why you’d need to hit it. Practically, it’s not needed to hit it. The most I did is 2 nests deep.

foo : check "isint(${1=0},0)"
  echo "Level : "$1
  foo {$1+1}

displays this:

$ gmic foo
[gmic]./ Start G'MIC interpreter (v.3.3.6).
Level : 0
Level : 1
Level : 2
Level : 3
(...)
Level : 59
Level : 60
Level : 61
[gmic] *** Error in ./foo/foo/foo/(...)/foo/foo/foo/foo/ (file '/home/tschumperle/.gmic', line #442) *** Call stack overflow (infinite recursion?).

which makes me realize that the limit is 61 not 64. I need to understand why…

Isn’t it funny what a matryoshka joke can do? :grinning:

To be honest, 64 is actually quite a low threshold.
It assumes that a G’MIC command that is recursive won’t be “too much” recursive, which is clearly a limitation of the framework.

In practice, I wonder how serious it is. I never had issues with this limitation so far.