The Big Bad G'MIC Thread of Silly Questions

EDIT: felt bad about opening a thread just for this so I’ll just use it for all the dumb questions I (you) may have in the future :laughing:


the other day I tried some basic stuff: gradually adjust luminosity or hue (anything with adjust_colors except saturation obviously) on a few full white/or gray/ or black images (Anything that’s filled with identical values, like 45,45,45, etc. ). And I don’t know if I’m doing things wrong again but it doesn’t seem to work. :person_shrugging:

gmic: GREYC's Magic for Image Computing: command-line interface
 Version 3.2.7 (pre-release #23081322)

This just outputs white images ( All pixels@255, and adding n 0,255 afterwards outputs black):
gmic run '400,400,1,3 fc 255,255,255 repeat 10 { +adjust_colors. -10 } d0 '

The same pipeline works on color images though (R values go from 255 to 112) and this is what i expect on white/grey images (or black images if i adjust positively):
gmic run '400,400,1,3 fc 255,0,0 repeat 10 { +adjust_colors. -10 } d0 '

So I tried this, with an almost full white image (and here values go from 255 to 254.4, which is not really visible, I eexpected a bit more :slight_smile: ):
gmic run '400,400,1,3 fc 255,255,254 repeat 10 { +adjust_colors. -10 } c 0,255 d0 '

Then I tried this and it doesn’t seem to work as it should ( is $> recognized here?) since all images end up the same light grey :
gmic run ' repeat 10 { 400,400,1,3,255 } repeat 10 { mul[$>] 0.9 } d0 '

Obviously this works but I need to adjust images that already exist:
gmic run ' 400,400,1,3,255 fc 255,255,255 repeat 10 { +mul. 0.9 } d0 '

So my question is : how can i adjust luminosity or hue correctly on this kind of images ? :thinking:

Thank you :slight_smile:


Command adjust_colors is intended to work for any type of float-valued image, so by default, it tries first to determine a “plausible” value range for the image values.
Here, with your extreme example where all values are the same, the command determines that the value range is indeed [255,255], so, any value transformation that tries to preserve this value range does actually nothing.

The solution here is to specify the image range when calling the command (parameters value_min and value_max). For your particular example, it would lead to:

 gmic 400,400,1,3,255 repeat 10 { +adjust_colors. -10,,,,0,255 } d0

1 Like

Ah! For some reason I forgot about these… Thanks!

But in the end i’d rather go with mul so I don’t end up with black too soon :
Do you know what’s wrong here? :

Well yes, you create a list of 10 images, then you multiply each image by 0.9.
You shoud use a different factor for each image, like in this example:

$ gmic 400,400,1,3,255x10 foreach { mul "{0.9^$>}" } d0

(I’ve added double quote to avoid being interpreter as bash special characters.

1 Like

Wow nice, i never used foreach before (except to englobe the whole script)… And I learned a new shortcut in the process (x10)!

But I still wonder why mul[$>] doesn’t work in my case? It seems to select all images instead of the one defined by $> ?

If we take a look at your example :

repeat 10 { mul[$>] 0.9 }

is actually equivalent to :

foreach { mul 0.9 }

which does nothing but multiply each image by the same factor 0.9.
At the end, all images are identical.

1 Like

Of course! I was thinking wrongly again :frowning:
I tend to try so many things at once that I often get lost.
My example would have worked on a single image like this :
gmic run '400,400,1,3,255 repeat 10 { +mul. 0.9 } d0'

I guess I should rest lol.
Sorry, I’m wasting your time, really.

No worry. What’s important is that you find a solution to your problem!


Thanks, I edited the 1st post. I’ll keep this thread for future small questions…

Well here one that’s been turning in my head for some time :

Take a look at this piece of code from Sloppy Mess (it is the intervaled/random mirroring part, added the gui lines for reference):

#@gui : Mirror Axis = choice("X-Axis","Y-Axis")  ##  $__mir
#@gui : Mirror Selection Interval (0:Off, -1:Random) = int(-1,-1,50)  ## $inter
#@gui : Invert Mirror Selection = bool(0,0,1)  ## $inv

 l[1--1] {
        if $inv==1 flip=^ fi
        if $inter>1
          ap[${flip}0--1:$inter] "mirror $__mir"
        elif $inter==-1
          repeat 2 {
            ap[${flip}0--1:{floor(u(1,20))}] "mirror $__mir"

And the question(s) :
Are such horrors allowed?
Does G’MiC like such nonsense as command decoration?
Should I decompose ap[${flip}0--1:{floor(u(1,20))}] into more vars?
Was I inspired or barely awake when i wrote this? I remember doing this in 2 mins and today I struggle on simple things like the previous post… Life is strange.

EDIT : It does look nice in Kate with all the pretty colors :

It looks fine to me, and is readable once you have experience with G’MIC. I have done much worse abomination than that. Wacky codes that are short are fine if they are readable and only localized in my opinion. Regex wouldn’t be a thing if they aren’t acceptable by coders. You can search using regex with search via KDE Kate there.

A few months ago I couldn’t even read this : l[1--1] :stuck_out_tongue:

Now I just hope squeezing all this into a command selection [] won’t break things someday. It’s not that it’s complex or anything, but the feature could be removed at some point. Also makes me wonder what kind of expression it can handle. Probably anything?
I could have done this to get the same results and looks more sane:

ap[$stuff]  blablabla...

But I don’t know why i cut it short and threw everything in the brackets.

And also $flip which doesn’t even exist when $inv=0… Should I make it like this :
if $inv==1 flip=^ else flip= fi or just leave it be (since it works anyway)?

And now i’m curious :slight_smile:
Btw I totally hate regex expressions :grimacing: Sometimes I have to use sed or awk but usually not in a very complex way (phew!).

It’s not likely that the feature would be removed. The only thing in the G’MIC language that is missing is a way to select arguments similar to what can be done with selecting images while depending on user input.

Here’s an abomination:

command "out2display : skip ${""1=},${""2=},${""3=},${""4=1},${""5=1},${""6=},${""7=},${""8=},${""9=},${""10=} if narg($""1) if $""1 $__bg rv blend alpha fi fi xalp if narg($""6) if narg($""2)&&narg($""3)&&narg($""4)&&narg($""5) {$""4},{$""5},1,{s#0},i(#-1,$""2+x,$""3+y) f. begin(ww=w-1;hh=h-1;);(x<(2+narg($""7))||x>ww-2)||(y<(2+narg($""7))||y>hh-2)?(xor($""6,i)>128?0:255):i j[0] [-1],$""2,$""3 rm. if narg($""8)&&narg($""9)&&narg($""10) if $""8==0||$""8>2 {$""4},{$""5},1,{s#0},i(#0,$__nw+($__min_tile*$""9)-$""2+x-$""4,$""3+y) f. begin(ww=w-1;hh=h-1;);(x<(2+narg($""7))||x>ww-2)||(y<(2+narg($""7))||y>hh-2)?(xor($""6,i)>128?0:255):i j[0] [-1],{$__nw+($__min_tile*$""9)-$""2-$""4},$""3 rm. fi if $""8==1||$""8>2 {$""4},{$""5},1,{s#0},i(#0,$""2+x,$__nh+($__min_tile*$""10)-$""3+y-$""5) f. begin(ww=w-1;hh=h-1;);(x<(2+narg($""7))||x>ww-2)||(y<(2+narg($""7))||y>hh-2)?(xor($""6,i)>128?0:255):i j[0] [-1],$""2,{$__nh+($__min_tile*$""10)-$""3-$""5} rm. fi if $""8==2||$""8>2 {$""4},{$""5},1,{s#0},i(#0,$__nw+($__min_tile*$""9)-$""2+x-$""4,$__nh+($__min_tile*$""10)-$""3+y-$""5) f. begin(ww=w-1;hh=h-1;);(x<(2+narg($""7))||x>ww-2)||(y<(2+narg($""7))||y>hh-2)?(xor($""6,i)>128?0:255):i j[0] [-1],{$__nw+($__min_tile*$""9)-$""2-$""4},{$__nh+($__min_tile*$""10)-$""3-$""5} rm. fi fi fi fi if narg($""7) f[0] begin(ww=w-1;hh=h-1;);(x%$__min_tile==0||y%$__min_tile==0)||(x==ww||y==hh)?$""7:i fi"
1 Like

I’d say the question would be rather : “is there any “better” way to do the same thing ?”
Of course, “better” is subjective of course, but it may imply for instance:

  • Shorter code.
  • More readable code.

These two properties may be in fact the opposite of each other, and then, the programmer will choose the one that seems most important for him.
On my side, it’s often “Shorter code” ;), because if you have to write a lot more code to do the same thing, then I think readability will suffer. Having one or two comments well placed is usually enough to make the code clear.

Above all, I think that taking advantage of the interpreted nature of the language is a good thing. So, defining a command name or an image selection depending on some conditions looks OK to me. I must admit doing this already saved me writing a lot of conditions in the past :slight_smile:

Your code could be rewritten like this (not tested though):

l[^0] {
  if $inv==1 sel..=^ fi  # Negate selection
  if $inter>1
    ap[$sel:$inter] "mirror $__mir"
  elif $inter==-1 
    repeat 2 {
      ap[$sel:$step] "mirror $__mir"

But that’s a personal taste of course.

@Reptorian That’s like, Lovecraft Level! :space_invader:

I like shorter code too, and I don’t like to repeat lines of code with a few variations.
But i’m not an expert either (yes you already know that), so what works first usually wins :grimacing: until i come back later and fix things ( which may not happen :stuck_out_tongue: )

l[^0] : Yes i knew about that one but for some reason i didn’t use it here… Strange.

Is that “backward” concatenation? Prefix? I suppose sel.=^ would append ^ to the content of $sel ?

step:=floor(u(1,20)) What is :=? I can’t find it in the reference. Is it to avoid using {}?

I quickly tested it and it was missing the final fi. Fixed that but now it’s missing a done command before return point. I’ll check that later and maybe do a mixture of both codes hihi.
It’s working now, thanks. Now i gotta chase all these var={stuff} to use :=



I also use that in case of when I want to treat string as a math parser code.

1 Like

I got you covered. You can search with \w+={.+?} after you enable regex searching.

20 matches using your file. Some false positives, but most work. You do have to be careful to set in vector arguments in some case, and in that case, might not be the best choice to fix it up.

To clarify:


The above code could be:


And this:


Could be:




In addition, this is unnecessary:

if {$colr+$cvar}<255&&{$colr+$cvar}>0 colr+=$cvar fi

You’re already using the math parser after the “if”. So, no {} is needed at all.
Could be rewritten as:

if inrange($colr+$cvar,0,255,0,0) colr+=$cvar fi
1 Like

Well, I’m afraid your “my file” is not up to date : i have 44 matches in mine :slight_smile:
And I have a separate dummy file for “unfinished & broken” business.
I’ll update once i fix those things. But each time i learn something here i have to re-check everything so the update may never happen at this rate x_x

Ah, Line Spam… I have to admit these values (formulas, whatever) are purely randomly chosen. It looked cool so why not? I tried all combinations i could think of, and removed the uglies.
I went in completely in the dark, as usual. Thanks for the advice, I will correct all this stuff. I still have to modify it for Spline Spam, after all. But i’ll have to find some nice values for the splines.

Really? ìf` calls the math parser? Didn’t know that… Some more stuff to check lol. Thanks, I hope I don’t use too much of your time. I could throw a billion questions…
( and i’m not the kind of guy to ask questions actually!)

@Reptorian is checking

That is how Rep and I learned: by asking questions :clap:, often ones with obvious answers. :sweat_smile: Not to fret though, this is a friendly community we have here for the most part. :wink:

Use this thread and threads such as G’MIC exercises for that purpose.


Also, this forum has a bookmark feature. Useful for going back.

1 Like