G'MIC exercises


Actually, I solved the emboss relief filter issue. The problem? @Joan_Rake1 has inserted the emboss/relief into her own gmic file. I had to remove the duplicate to make it work. And yes, she’s here. There is a duplicate construction material as well, but that’s not going to interfere anyway as the two commands are different.

emboss is in it own cli command now.

em $1,$2,$3,$4

$1 = smoothness
$2 = angle
$3 = depth
$4 = depth boost

em = emboss_image


To avoid confusion, I suggest you add a prefix to all of your commands; e.g., @garagecoder uses gcd_.

1 Like
(dumb) #342

Note taken. I’ve removed mine anyway since they’re obsolete.


Never mind, I actually get it. That is tricky.

(dumb) #344
+r {100/(2^$iter)}%,{100/(2^$iter)}%
repeat $iter
fx_local_processing[-1] 1,100,1,0,0,0,7,0,50,50
resize[-1] 200%,200%
resize[-1] {w(#0)},{h(#0)}
blend xor

Try screwing with this.


@David_Tschumperle @afre

if {$AlpC<2} v + error "Check inputs again -  > 0 ? $5>1 : $4>1" fi

I’m stuck on the part of error, and I would like the output to show $2>0?$5>1:$4>1

My current workaround

if {$AlpC<2} if $2 v + error "As Variable 2 is greater than 0, variable 5 must be greater than 1" 
else v + error "As Variable 2 is equal to 0, Variable 4 must be greater than 1" fi fi

Also, first time working with error messages.


I know you want to learn how to output the message. I will let David answer that part.

My opinion on the matter:

  • Why not make the parameters no greater than 1 from the start? Also, the GUI isn’t dynamic; it won’t change based on conditionals. It is poor filter design even if it were CLI only.
  • There is no way the user would understand what $2>0?$5>1:$4>1 means. The statement is confusing for me as well.

The thing is I don’t know how I can change the CLI to make more sense. The palette transfer CLI second option determines the style of transfer, and if it activated, $4 becomes a new parameter for the style.

So, $2>0?$5>1:$4>1 translate to Indexing_Style (0 = Regular,1 = Noise, 2= Luminance-Based Indexing, 3 = Horizontal, 4 = Vertical)? $5 is the alpha count value : $4 is the alpha count value

I know, it’s confusing, but it’s the best I can do with this. I also added pal_i where if you put pal i, you can transfer palette based on 2 image inputs while it’s separate from the pal numbers series.


What I would do is

AlpC=$4 AlpD=$5 SF=$6

So, basically

Palette_Number or Palette_Name = $1
Special_Style_Effect Variable=$6

That makes sense. Removes the need for dynamic CLI. I do have to admit that I was testing dynamic variable to see what makes the most sense as I wasn’t sure how to make the CLI. And then I have the issue of using pal i effectively.

_pal_i: +autocrop if {h#2<h#3} autocrop[0] to_rgb[0] rv[0-1] else autocrop[1] to_rgb[1] fi rm[^0-1]

Is there a way to do the above easier? I didn’t want to change the main image size. But palette is treated as a small sized image. I might have to put a error message to verify that the palette layer is 1 px high.


I am unsure of what you are trying to achieve there. Could you explain in plain English what you are trying to do?

Re: both the dynamic variable question and the _pal_i one. My take is to see how stdlib handles this problem, unless it is a G’MIC core thing, in which case you examine cimg(?).


What I’m trying to achieve is a CLI command where I insert which palette to use, and the style to use, alpha-count, alpha-dithering, and if it a special style, use an additional variable for special style.

A lot like reduced color transfer filter I made with palette as the reference, but improved in as new feature which is style support, and being able to treat one of the two layers as a palette if i is typed in as the first option.

stdlib (I looked at it, but it’s a little long, but I’ll look at it again). Haven’t seen cimg.


I was referring to


Imagine you have two different images where one layer is the 1px high palette. _pal_i basically automatically convert a palette layer into 1px high gmic layer in the place of [1]. The smaller layer is always image[1]. Pal 2 generates a palette into [1].


Is there a way to suppress verbose message? The message ‘1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1’ when using at or apply_tiles doesn’t really make things productive when testing code via g’mic. v 0 doesn’t suppress it. So, here I’m left picturing it in my head.


Maybe verbose -1.

BTW, the multiple edits make your posts hard to follow. I use “PS” and “edit” to indicate any updates.


I tried that.

Actually, I have a better idea

@David_Tschumperle Do you think you could remove the verbose message on apply_tiles? It is intrusive when testing codes with apply_tiles via code[local] or code[global]. Especially when tiles are really small.


I am still struggling with scripting. I know I could examine the *.gmic files but my eyes glaze over. I need a real simple example. We may have covered something similar already: I want to learn to create a map showing local stats. Could be anything, say SNR, for a given window. E.g., below, s represents the SNR of a 5x5 window with a boundary condition of mirror.

x x x x x
x x x x x
x x s x x
x x x x x
x x x x x

So, we will end up with a map of ses with the same dimensions as the input image.

I guess where I want to go with this eventually is creating maps of all sorts to guide, or to be conditions or comparisons, for other processing.

(G'MIC staff) #361

When you want to do custom things locally on pixels, it’s often relevant to use the fill command with a math expression.
For instance, the command below computes the value average(N)/(30+std(N)) for each 5x5 neighborhood N of the input image (doing this for each channel separately):

foo :
  sp car
  f "
    const boundary = 3;
    N = crop(x-2,y-2,0,c,5,5,1,1);
  n 0,255

leading in a kind of cartoon version of the input image:

In the math expression, N is the vector of all unrolled values of your 5x5 neighborhood.
You can compute almost anything you want from these values.

1 Like

Thanks! Regarding crop():

  • What is the difference between declaring boundary conditions with const boundary and _boundary_conditions? (Does const mean that it applies to all operations involving the boundaries and not just crop()? Or are there other distinctions?)

  • What does a parameter without a variable mean? Why is it 0 instead of d?

  • What happens when parameters are omitted? What would crop(100,100) do?

One more question:

  • Any reason for the 30? (Is it an arbitrary number or any way related to the window size?)