The Big Bad G'MIC Thread of Silly Questions

A good strategy here is to put all values in a single image, then reshape/rearrange that image to build a colormap. Like in this example:

#@gui Filter : my_filter
#@gui : Color1 = color(0,0,0)
#@gui : Color1 = color(255,0,0)
#@gui : Color1 = color(0,255,0)
#@gui : Color1 = color(0,0,255)
#@gui : Color1 = color(255,255,0)
#@gui : Color1 = color(255,0,255)
#@gui : Color1 = color(0,0,255)
my_filter :
  (${1-21}) r. 3,7,1,1,-1 permute. yzcx => colormap
  foreach[^-1] { pass[colormap] index[0] [colormap],1,1 rm[colormap] }

Use boundary_conditions=2 (periodic) when accessing the image palette. So you don’t have to worry about the fact your index is out-of-range or not:

my_filter :
  (${1-21}) r. 3,7,1,1,-1 permute. yzcx => colormap
  foreach {
    pass[colormap]
    +f[0] "I[#$colormap,R,2]" k.
  }

(here I use the value of the Red channel of each pixel (in [ 0,255 ]), as a colormap index (which has only 7 entries).

2 Likes

Thanks, that works for me and much, much easier to maintain!
(${11-34}) r. 3,8,1,1,-1 permute. yzcx =>. PAL
Though i’m using it more like a color swatch or picker to draw stuff with rather than indexing (Hence the I loop).

Now to define more color boxes…

And another question: how would you replace rotations as they can be time consuming when spammed on larger images?
This took 4s to render ( 1707x1048):

I can imagine it’ll be way longer on larger images.

The first question to ask is “why and when you use rotation ?”.
If I understand well, your image is “just” composed of lot of circles (or ellipses), so a way to render such an image would be to first generate a list of circle coordinates (x,y,radius) where your coordinates take the successive rotations into account (and it’s way faster to rotate a vector-representation of your image than the complete image).

That would probably mean : “Rethink a bit about how the algorithm works and make it more optimal in the sense of data structures used”.
That may be a lot of work.

But that’s often the difference between a code snippet that is intended to be short, and a filter implementation, that is intended to be efficient :wink:

Why : to easily switch the position of the circles/ellipses (random angle and random center of rotation) without thinking too much about it , while taking benefit from mirroring boundaries and interpolation
When : every Nth loop

Well, without going as far as planning all the ellipses coordinates (huh!) i could just … mmm translate the origins (is that the term?) to another part of the image and continue from there, as if it was rotated? Not sure i can do that but i can try.

I guess optimisation always comes last for me, i’m going for the visuals first :stuck_out_tongue:

Anyway, here’s 16 colors :


They don’t always look that good though.


Aaaaaah, color boxes xD
I think maybe i could add a file input so i can to pick colors from it…

3 Likes

Thank you for the brilliant idea. I will do this for my gui_util_pal command.

2 Likes

Hello everyone!

I’m trying to figure out why this part of the code :

If code
     repeat 4 {
         if $>==0 nx,ny,nxb,nyb=$x,$y,$xb,$yb
           elif $>==1 nx,ny=$x nxb,nyb=$xb
           elif $>==2 nx,ny,nxb,nyb=$y,$x,$yb,$xb
           else nx,ny=$y nxb,nyb=$yb
         fi
         ellipse[0] $nx%,$ny%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
         if $dbl
           if $dir ang:=$<*$angle fi
             ellipse[0] $nxb%,$nyb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
         fi
     }


Ugly!

…does not output the same image as this ?

Spam code
    ellipse[0] $x%,$y%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
    ellipse[0] $x%,$x%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
    ellipse[0] $y%,$x%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
    ellipse[0] $y%,$y%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
    if $dbl
      if $dir ang:=$<*$angle fi
        ellipse[0] $xb%,$yb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
        ellipse[0] $xb%,$xb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
        ellipse[0] $yb%,$xb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
        ellipse[0] $yb%,$yb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
    fi


Bettery!

I think they should be equivalent? I think…

Also, is there a reason why these vars work :

 col1={[$-6,$-5,$-4]} 
 col2:=[255,0,0]

but this one doesn’t ?

 col1:=[$-6,$-5,$-4]
Full (really) dumb script below :
#@gui Sketchy Ellipses : pr_sketchy_ellipses, pr_sketchy_ellipses(1)*
#@gui : Amount = int(2000,100,5000)
#@gui : Center X = ~float(35,0,100)
#@gui : Center Y = ~float(35,0,100)
#@gui : Center XB = ~float(35,0,100)
#@gui : Center YB = ~float(35,0,100)
#@gui : Increment X = ~float(7,-10,10)
#@gui : Increment Y = ~float(4,-10,10)
#@gui : Increment XB = ~float(4,-10,10)
#@gui : Increment YB = ~float(4,-10,10)
#@gui : Inc Modifier  = ~int(1000,10,1000)
#@gui : Ratio = ~float(2,0.1,5)
#@gui : Increment Size = float(4,1,10)
#@gui : Angle Factor = ~float(1,.01,10)
#@gui : Add B Set = ~bool(1)
#@gui : Invert B Direction = ~bool(1)
#@gui : Opacity = float(.3,.01,1)
#@gui : Line Pattern = text(0,0xFFFFFFFF)
#@gui : Color 1 = ~color(0,0,0)
#@gui : Color 2 = ~color(255,255,255)
pr_sketchy_ellipses:
foreach {
  amount,x,y,xb,yb,SX,SY,SXB,SYB,boost,ratio,Rinc,angle,dbl,dir,op,pat=${1-17}
  col1={[$-6,$-5,$-4]}
  col2={[$-3,$-2,$-1]}
  SX,SY,SXB,SYB/=$boost
  Rinc/=100
  S=0
  repeat $amount {
    opac:=u($op)
    ang:=$>*$angle

    # repeat 4 {
    #     if $>==0 nx,ny,nxb,nyb=$x,$y,$xb,$yb
    #       elif $>==1 nx,ny=$x nxb,nyb=$xb
    #       elif $>==2 nx,ny,nxb,nyb=$y,$x,$yb,$xb
    #       else nx,ny=$y nxb,nyb=$yb
    #     fi
    #     ellipse[0] $nx%,$ny%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
    #     if $dbl
    #       if $dir ang:=$<*$angle fi
    #         ellipse[0] $nxb%,$nyb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
    #     fi
    # }

    ellipse[0] $x%,$y%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
    ellipse[0] $x%,$x%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
    ellipse[0] $y%,$x%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
    ellipse[0] $y%,$y%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
    if $dbl
      if $dir ang:=$<*$angle fi
        ellipse[0] $xb%,$yb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
        ellipse[0] $xb%,$xb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
        ellipse[0] $yb%,$xb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
        ellipse[0] $yb%,$yb%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col2
    fi

    x,y+=$SX,$SY
    xb,yb+=$SXB,$SYB
    S+=u($Rinc)
  }
  n 0,255
}

Beware that the line:

if $dir ang:=$<*$angle fi

will probably consider different values for $< in the two versions (in the second one in particular, $< in the decreasing index for foreach which is probably 0 if you have only a single image).

Its should be equivalent. What difference do you see?

When i used col1:=[$-6,$-5,$-4] i got an error with ellipse not recognizing the color values. Maybe i missed something at that time, but when i used col1={[$-6,$-5,$-4]} it started working. But, looks like it works with both now :open_mouth: So i’m really confused…

mmm… I think i need 2 x repeat to have the same output.

Or maybe not. I think you where right about $< so i moved it out of the loop:

repeat $amount {
    opac:=u($op)
    ang:=$>*$angle
    if $dir Bang:=$<*$angle else Bang=$ang fi
    repeat 4 {
        if $>==0 nx,ny,nxb,nyb=$x,$y,$xb,$yb
          elif $>==1 nx,ny=$x nxb,nyb=$xb
          elif $>==2 nx,ny,nxb,nyb=$y,$x,$yb,$xb
          else nx,ny=$y nxb,nyb=$yb
        fi
        ellipse[0] $nx%,$ny%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
        if $dbl
            ellipse[0] $nxb%,$nyb%,$S%,{$S*$ratio}%,$Bang,$opac,$pat,$col2
        fi
    }
    x,y,xb,yb,S+=$SX,$SY,$SXB,$SYB,u($Rinc)
  }


Thanks!

Now, you’re thinking like a experienced G’MIC coder.

Also, do ${-6--4} instead.

1 Like

Also:

nx,ny,nxb,nyb:=arg0($>,[$x,$y,$xb,$yb],[$x,$x,$xb,$xb],[$y,$x,$yb,$xb],[$y,$y,$yb,$yb])
1 Like

Errrr. Not really? All i can say is that 99.9% of what i do with G’mic comes from my poor little head. I really don’t search for inspiration or information beforehand. I just try things and see what happens.
So yesterday, out of curiosity, i just went to check “ellipse” on wikipedia and found out that what the output i just got is pretty common lol. And there i was happy to get some spiral (or whirls like they say) with some crappy script and a bunch of ellipses hehe. Well, at least it looks sketchy.

Thanks, forgot about this though i use for every GUI script…
Since col=${-6--4} doesn’t work (too many values for 1 var), should i write it like this?
ellipse[0] $nx%,$ny%,$S%,{$S*$ratio}%,$ang,$opac,$pat,${-6--4}
But then how can I change the colors from within the loop without adding a whole ellipse line?

Ah yes thanks, that’s shorter indeed, but still a bit harder to decypher for me.
I keep forgetting about “utility” commands, and tend to think with if this else that fi logic.

Hum. That should work:

$ gmic col=1,2,3 e \$col
[gmic]./ Start G'MIC interpreter (v.3.5.2).
[gmic]./ Set local variable 'col=1,2,3'.
1,2,3
[gmic]./ End G'MIC interpreter.

Then:

nx,ny,nxb,nyb:=$>==0?[$x,$y,$xb,$yb]:\
               $>==1?[$x,$x,$xb,$xb]:\
               $>==2?[$y,$x,$yb,$xb]:\
                     [$y,$y,$yb,$yb])`

Sorry, it’s probably my fault again. I actually did multiple var assignment like this :

col1,col2=${-6--4},${-3--1}
or 
col1,col2=${-6--4,-3--1}

I guess G’mic translates this as just col1,col2=1,2,3,4,5,6 which doesn’t work.

Then:

nx,ny,nxb,nyb:=$>==0?[$x,$y,$xb,$yb]:\
               $>==1?[$x,$x,$xb,$xb]:\
               $>==2?[$y,$x,$yb,$xb]:\
                     [$y,$y,$yb,$yb])`

I wonder how many different syntaxes are in G’mic… So many ways to do the same things :slight_smile: How can you remember them all?

Exactly.

Because I wrote the language ? :wink:

Because you use it, i’d say! I write many things that i never remember afterwards :slight_smile:

To do this, you can do this:

foo:
col1,col2="${-6--4}","${-3--1}"

Debug print:

C:\WINDOWS\System32>gmic debug foo 1,2,3,4,5,6
[gmic]./ Start G'MIC interpreter (v.3.5.1, debug mode).
<gmic>./ Initial command line: 'cli_start , debug foo 1,2,3,4,5,6'.

<gmic>./ Enter scope './'.
<gmic>./ Item[0]: 'cli_start', selection [].
<gmic>./ Found custom command 'cli_start:  _display_print_images=inf l[] m 1,$_path_user onfail done' (takes no arguments).
<gmic>./ Expand command line for command 'cli_start' to: ' _display_print_images=inf l[] m 1,$_path_user onfail done'.
<gmic>./ Decompose command line into 9 items:
<gmic>./   item[0] = (debug info 0x1)
<gmic>./   item[1] = (debug info 0x2)
<gmic>./   item[2] = '_display_print_images=inf'
<gmic>./   item[3] = (debug info 0x3)
<gmic>./   item[4] = 'l[]'
<gmic>./   item[5] = 'm'
<gmic>./   item[6] = '1,$_path_user'
<gmic>./   item[7] = 'onfail'
<gmic>./   item[8] = 'done'

<gmic>./cli_start/ Enter scope 'cli_start/'.
<gmic>./cli_start/#2 Item[2]: '_display_print_images=inf', selection [].
[gmic]./cli_start/ Set global variable '_display_print_images=inf'.
<gmic>./cli_start/#3 Item[4]: 'l[]', selection [].
[gmic]./cli_start/*local#3/ Start 'local...done' block, with image [].

<gmic>./cli_start/*local#3/#3 Enter scope '*local#3/'.
<gmic>./cli_start/*local#3/#3 Item[5]: 'm', selection [].
<gmic>./cli_start/*local#3/#3 Command 'command': arguments = '1,$_path_user' -> '1,C:\Users\Miguel\user.gmic'.
[gmic]./cli_start/*local#3/ Import commands from file 'C:\Users\Miguel\user.gmic', with debug info (43 replaced, total: 4714).
<gmic>./cli_start/*local#3/#3 Item[7]: 'onfail', selection [].
<gmic>./cli_start/*local#3/#3 Item[8]: 'done', selection [].
[gmic]./cli_start/*local#3/ End 'local...done' block.
<gmic>./cli_start/*local#3/#3 Exit scope '*local#3/'.

<gmic>./cli_start/#3 Exit scope 'cli_start/'.

<gmic>./ Item[2]: 'debug', selection [].
<gmic>./ Item[3]: 'foo', selection [].
<gmic>./ Found custom command 'foo:  col1,col2="${-6--4}","${-3--1}"' (takes arguments).
<gmic>./ Command 'foo': arguments = '1,2,3,4,5,6'.
<gmic>./ Found 6 given arguments for command 'foo':
<gmic>./   $1 = '1'
<gmic>./   $2 = '2'
<gmic>./   $3 = '3'
<gmic>./   $4 = '4'
<gmic>./   $5 = '5'
<gmic>./   $6 = '6'
<gmic>./ Expand command line for command 'foo' to: ' col1,col2="1,2,3","4,5,6"'.
<gmic>./ Decompose command line into 3 items:
<gmic>./   item[0] = (debug info 0x13b,1)
<gmic>./   item[1] = (debug info 0x13c,1)
<gmic>./   item[2] = 'col1,col2=1\,2\,3,4\,5\,6'

<gmic>./foo/ Enter scope 'foo/'.
<gmic>./foo/#316 Item[2]: 'col1,col2=1\,2\,3,4\,5\,6', selection [].
[gmic]./foo/ Set variables 'col1=1,2,3' and 'col2=4,5,6'.
<gmic>./foo/#316 Exit scope 'foo/'.

The following line is proof it works:

[gmic]./foo/ Set variables 'col1=1,2,3' and 'col2=4,5,6'.
2 Likes

But still, ellipse is very picky :

Show the whole code, so we can test it.

EDIT : just so you know, replace ellipse with circle and the var works.
Got the same problem a few days ago when using $> in a var:

  if $size S="$>" else S="$<" fi
    repeat 1000 {
       if $motif 
         ellipse 50%,50%,$S,$S,0,1,0xFFFFFFFF,255 
       else 
         circle 50%,50%,$S,1,0xFFFFFFFF,255
      fi
}

Ellipse returns : invalid argument 50%,50%,$>,$>...
Is it treating $> as text? circle really works here though.
Did this to avoid setting S a thousand times.

Code is already there in a previous post but i’ll paste the latest version here:

#@gui Sketchy Ellipses : pr_sketchy_ellipses, pr_sketchy_ellipses(1)*
#@gui : Amount = int(2000,100,5000)
#@gui : Center X = ~float(35,0,100)
#@gui : Center Y = ~float(35,0,100)
#@gui : Center XB = ~float(35,0,100)
#@gui : Center YB = ~float(35,0,100)
#@gui : Increment X = ~float(7,-10,10)
#@gui : Increment Y = ~float(4,-10,10)
#@gui : Increment XB = ~float(4,-10,10)
#@gui : Increment YB = ~float(4,-10,10)
#@gui : Inc Modifier  = ~int(1000,10,1000)
#@gui : Ratio = ~float(2,0.1,100)
#@gui : Increment Size = float(4,1,10)
#@gui : Angle Factor = ~float(1,.01,10)
#@gui : Add B Set = ~bool(1)
#@gui : Invert B Direction = ~bool(1)
#@gui : Opacity = float(.3,.01,1)
#@gui : Line Pattern = text(0,0xFFFFFFFF)
#@gui : Color 1 = ~color(0,0,0)
#@gui : Color 2 = ~color(255,255,255)
pr_sketchy_ellipses:
foreach {
  amount,x,y,xb,yb,SX,SY,SXB,SYB,boost,ratio,Rinc,angle,dbl,dir,op,pat=${1-17}
  # col1=${-6--4}
  # col2=${-3--1}
  col1,col2="${-6--4}","${-3--1}"
  SX,SY,SXB,SYB/=$boost
  Rinc/=100
  S=0
  repeat $amount {
    opac:=u($op)
    ang:=$>*$angle
    if $dir Bang:=$<*$angle else Bang=$ang fi
    repeat 4 {
        nx,ny,nxb,nyb:=arg0($>,[$x,$y,$xb,$yb],[$x,$x,$xb,$xb],[$y,$x,$yb,$xb],[$y,$y,$yb,$yb])
        ellipse[0] $nx%,$ny%,$S%,{$S*$ratio}%,$ang,$opac,$pat,$col1
        if $dbl
            ellipse[0] $nxb%,$nyb%,$S%,{$S*$ratio}%,$Bang,$opac,$pat,$col2
        fi
    }
    x,y,xb,yb,S+=$SX,$SY,$SXB,$SYB,u($Rinc)
  }
  n 0,255
}

I’ll probably put a slider for S, which is the starting size. And rename Angle factor to multiplier… S’cuse my poor maths memory :stuck_out_tongue: