G'MIC exercises

What I"m trying to do is to use the crop of the input value which would be the very big set of number inside (). It should go something on the line of this.

rep_binaltquad.  {crop(#2,8+11*0,0,15+11*0,1)},256,256,{crop(#2,15+11*0,0,16+11*0,1)}
rep_binaltquad.  {crop(#2,8+11*1,0,15+11*1,1)},256,256,{crop(#2,15+11*1,0,16+11*1,1)}
rep_binaltquad.  {crop(#2,8+11*2,0,15+11*2,1)},256,256,{crop(#2,15+11*2,0,16+11*2,1)}

I know direction matters. I chose $> for the parts that matters. I can fix the $< later on. If it works exactly like above, then it should work on the output.

Solved the problem :

v1=0
v2=0
v3=0
v4ch1=0
v5ch2=1
v6ch3=2
v7ch1=0
v8ch2=1

v9_vsty=1
v10_v1=8
v11_v2=8
v12_v3=128
v13_op=2
v14_ang=45
v15_x=0
v16_y=0
v17_n=1

v18_vsty=1
v19_v1=8
v20_v2=8
v21_v3=128
v22_op=2
v23_ang=45
v24_x=0
v25_y=0
v26_n=1

v31_vsty=1
v32_v1=8
v33_v2=8
v34_v3=128
v35_op=2
v36_ang=45
v37_x=0
v38_y=0
v39_n=1

v40_vsty=1
v41_v1=8
v42_v2=8
v43_v3=128
v44_op=2
v45_ang=45
v46_x=0
v47_y=0
v48_n=1

v49_vsty=1
v50_v1=8
v51_v2=8
v52_v3=128
v53_op=2
v54_ang=45
v55_x=0
v56_y=0
v57_n=1

cs_mode=$v1
cmyk_mode={$cs_mode==3?4:3}
contain_alpha={$v2?1:0}
bitmode=$v3
tch={$cmyk_mode+$contain_alpha}

channels 0
r 100%,100%,100%,$tch

if {$tch==3} ($v4ch1,$v5ch2,$v6ch3)
elif {$tch==4} ($v4ch1,$v5ch2,$v6ch3,$v7ch1)
elif {$tch==5} ($v4ch1,$v5ch2,$v6ch3,$v7ch1,$v8ch2)
fi 

tc={w#1} s. x remove_duplicates tw={$!-1} if $tw<$tc v + error "Invalid Channel Order!" v - fi 

a[^0] x rv
($v1,$v2,$v3,$v4ch1,$v5ch2,$v6ch3,$v7ch1,$v8ch2,$v9_vsty,$v10_v1,$v11_v2,$v12_v3,$v13_op,$v14_ang,$v15_x,$v16_y,$v17_n,$v18_vsty,$v19_v1,$v20_v2,$v21_v3,$v22_op,$v23_ang,$v24_x,$v25_y,$v26_n,$v31_vsty,$v32_v1,$v33_v2,$v34_v3,$v35_op,$v36_ang,$v37_x,$v38_y,$v39_n,$v40_vsty,$v41_v1,$v42_v2,$v43_v3,$v44_op,$v45_ang,$v46_x,$v47_y,$v48_n,$v49_vsty,$v50_v1,$v51_v2,$v52_v3,$v53_op,$v54_ang,$v55_x,$v56_y,$v57_n)

if ($cs_mode==3||(($cs_mode>8&&$cs_mode<11)||$cs_mode<3))||$bitmode (256,256,256,256,256)
else
    if $cs_mode>3&&$cs_mode<7 (361,101,101,256)
    elif $cs_mode==7 (101,201,201,256)
    elif $cs_mode==8 (101,129,{ceil((pi)*200)},256)
    elif $cs_mode==11 (301,301,301,256)
    elif $cs_mode==12 (256,301,301,256)
    elif $cs_mode==13 (301,301,301,256)
    fi
fi
fact=9
repeat $tch
sh[1] {i(#0,$>,0)}
rep_binaltquad. {i(#2,8+$fact*$>,0)},{i(#2,9+$fact*$>,0)},{i(#2,10+$fact*$>,0)},{i(#2,11+$fact*$>,0)},{i(#2,12+$fact*$>,0)},{i(#2,13+$fact*$>,0)},{i(#2,14+$fact*$>,0)},{i(#2,15+$fact*$>,0)},{i(#3,$<,0)},{i(#3,$<,0)},{i(#2,16+$fact*$>,0)}
rm.
done
k[1]

I decided to go for that approach as for some reason, crop approach didn’t really worked out.

I’ve been a little interested in the Hough transform and I want to make an inverse command but it seems to involve pointclouds and I’m not sure where to start at all. There is a paper on it but I’m stuck at the part where it’s banging on about binarised images and anything beyond that.
https://www.researchgate.net/publication/3193068_On_the_Inverse_Hough_Transform

search_dichotomic commands are slow but I use them all of them time. I wanted to see if I could save time by optimizing the code. Any thoughts on this would be appreciated!

I noticed that @David_Tschumperle included the search function as a macro in the stdlib; however, @garagecoder showed me that using it would actually be more expensive. His suggestion was to break up the fill into separate commands and place as many outside of the search as possible.

I tried a bunch of variants of the command and so far the best combination is

afre_sl: skip ${1=.5}
  repeat $! l[$>] r={[im,iM]} n 0,1
    search_dichotomic "
      +* -1 +. 1 f. i^$""1 *. -1 +. 1 t={ia} rm. u $t
    ",$1,1e-3 * -1 + 1 f i^${} * -1 + 1
  n $r endl done

One thing I noticed was that the use of pow is problematic in two ways. If used after search to process the actual image, it would slow it down 6-14s for a large image. In contrast, inside of search, it makes the command 3-4s faster. However, the 3-4s isn’t worth it since pow causes the search to fail on certain images, which is definitely not desirable!

I don’t have an explanation for this. My guess is that the precision is different and both are programmed and optimized differently.


Uncertain if the optimization of afre_sl is complete but I am already wondering how I would optimize search for

afre_c: skip ${1=2}
  n 0,1 f if(i<ia,ia*(i/ia)^$1,1-(1-ia)*((1-i)/(1-ia))^$1)

For brevity, I am showing the curve by itself. This one is piece wise, so I don’t know how I would go about breaking it up. So far, I find that changing ia*(i/ia)^$1 to ia^(1-$1)*i^$1 seems to speed it up a bit. Again, I don’t know why it is faster.

Alternatively, I could try using a non piece wise curve instead; several have been discussed earlier in this thread that might be worth visiting. Still, I am partial to afre_c.

f "vx=x-w/2;vy=y-h/2;ang=pi/4;I=I(vx*cos(ang)+vy*sin(ang)+w/2,vy*cos(ang)-vx*sin(ang)+h/2)"

…is a centered rotate command which comes with a lot of potential. I can already create a much faster layer cake script than the original one:

f "vx=x-w/2;vy=y-h/2;num=10;ang=(pi/num*round(norm(vx,vy),norm(w,h)/(2*num),-1))%(pi*2);I=I(vx*cos(ang)+vy*sin(ang)+w/2,vy*cos(ang)-vx*sin(ang)+h/2,z,2,2)"

I cannot yet figure out how to make a kaleidoscope script out of it though. My aim is to make one that works like the GEGL script that’s bundled with G’MIC.

Edit: I have something, but it’s not quite mirrored like the GEGL script.

f "vx=x-w/2;vy=y-h/2;num=2;ang=(round(atan2(vy,vx),pi/6,1))%(pi*2);I=I(vx*cos(ang)+vy*sin(ang)+w/2,vy*cos(ang)-vx*sin(ang)+h/2,z,2,2)"
1 Like

flowerk

Never used the GEGL script before, so I don’t know what it is supposed to look like. I did a web search. Second link seems interesting: https://www.csh.rit.edu/~pat/hack/quickies/kaleid/.

Yeah, the mirrored style shown on the linked page is what I’m going for. Using:

f "vx=x-w/2;vy=y-h/2;num=3;amult=round(atan2(vy,vx),pi/num,1);ang=(amult)%(pi*2);
xwarp=vx*cos(ang)+vy*sin(ang)+w/2;
ywarp=vy*cos(ang)-vx*sin(ang)+h/2;
(floor(2*amult%(2*pi/num)))?(I=I(xwarp,ywarp,z,2,3)):(I=I(xwarp,ywarp,z,2,3))"

…I can target every second strip, but I still haven’t been able to figure out how to get it to mirror.

I also have a more generic rotation command:

xc=0.5
yc=0.5
f "xoff=w*"$xc";
yoff=h*"$yc";
vx=x-xoff;vy=y-yoff;
ang=(0.5*2*pi)%(2*pi);I=I(vx*cos(ang)+vy*sin(ang)+xoff-1,vy*cos(ang)-vx*sin(ang)+yoff-1,z,2,2)"

The only issue is that when the angle is 180 degrees it clearly shows that centre of rotation is not at the centre of the image because there’s a slight offset.

Edit: this doesn’t seem to have that defect.

xc=0.5 yc=0.5
ang=pi
f "begin(ang=("$ang")%(2*pi);xoff=w*"$xc";yoff=h*"$yc");
vx=x-xoff+0.5;vy=y-yoff+0.5;
I=I(vx*cos(ang)+vy*sin(ang)+xoff-0.5,vy*cos(ang)-vx*sin(ang)+yoff-0.5,z,2,3)"

I want to know how I can mirror an image using an arbitrary line using f since using rotate and mirror means that I have to use some mathematical trickery to get the angles of the mirroring and the kaleidoscope strip process to match up. Besides that, I have an improved version of the layer cake script:

xc=0.5
yc=0.5
num=3
ang={2*pi/($num-1)}
f "begin(ang=("$ang")%(2*pi);xoff=w*"$xc";yoff=h*"$yc";num="$num");
vx=x-xoff+0.5;vy=y-yoff+0.5;
angle=(ang*floor(norm(vx,vy)/norm(w,h)*2*num));
I=I(vx*cos(angle)+vy*sin(angle)+xoff-0.5,vy*cos(angle)-vx*sin(angle)+yoff-0.5,z,2,3)"

A small tip (not the answer to your question, sorry)… you can specify default boundary conditions and interpolation inside the “begin” section:

gmic sp rooster f "begin(T=pi/8;boundary=0;interpolation=2;A=cos(T);B=sin(T);M=[A,B,-B,A];C=[w/2,h/2];C-=M*C);I(M*[x,y]+C)"
1 Like

I can use that to make a nicer version of twirl which doesn’t have as many of the odd broken streak artefacts and adds a power option:

f "begin(boundary=3;interpolation=2);P=[x,y];C=[w/2,h/2];T=pi*10*(norm(P-C)/(norm(w,h)*2))^0.5;A=cos(T);B=sin(T);M=[A,B,-B,A];C-=M*C;I(M*P+C)"

It is a slow day for me. :dizzy_face:  I am having trouble making half-kernels.

Loops are confusing. E.g.,

loop1: 5,1,1,1,1 f for(k=0,k<w,++k,i(k)=k)
loop2: 5,1,1,1,1 f for(k=0,k<(w-1)/2,++k,i(k)=0)

Command, Expectation, Result
loop1, (0,1,2,3,4), (0,1,2,3,5)
loop2, (0,0,1,1,1), (0,0,0,0,0)

If I set k<w-1 in loop1, then it works, but I don’t get why it should. Isn’t k counting from 0 to 3, filling values in those positions? If I set i(k)=k in loop2, the result is (0,1,2,2,2). I would have thought it to be (0,1,1,1,1).


I decided to use if-statements (which I am more comfortable with) in the place of loops. Still, I would like to see how it is supposed to be done with the latter.

5,1,1,1,1 +f x<(w-1)/2?0:i +f.. x>(w-1)/2?0:i
# (1,1,1,1,1) (0,0,1,1,1) (1,1,1,0,0)

Now that I have my kernel, I want to use it for 2d convolution. Octave has conv2 (MATLAB docs). What is the G’MIC equivalent of conv2(kernel,kernel,image,'same')-image? The Octave output is as follows

kernel =
   0.50000
   0.50000
   0.00000

image =
   218.000   218.000   236.500   216.000   196.500    72.000    72.000
   218.000   218.000   236.500   216.000   166.500    72.000    72.000
   209.500   209.500   102.500   117.500    88.500    36.000    18.000
   137.000   137.000   147.000   107.500   133.500   119.000   119.000
   137.000   137.000   147.000   128.500   133.500   119.000   119.000

ans =
     0.00000    18.50000   -20.00000   -18.50000   -53.00000     0.00000   -36.00000
    -8.50000   -45.00000  -101.50000   -63.50000   -93.75000   -36.00000   -54.00000
   -32.00000   -72.75000    84.50000    -8.50000     1.50000    59.50000    29.75000
     0.00000    10.00000   -24.00000    19.50000   -14.50000     0.00000   -59.50000
   -68.50000   -63.50000   -90.50000   -44.75000   -81.25000   -59.50000   -89.25000

The fill command is already a loop over each pixel, so you’re doing a loop within a loop on each pixel. To avoid that, use something like 5,1,1,1,1 eval "for(k=0,k<w,++k,i(k)=k)". That would be equivalent to 5,1,1,1,1 f x or simply 5,1,1,1,x (so long as it’s 1D along x axis).

I think you made a mistake somewhere, that’s not the correct output! Anyway, conv2 in that form is simply equivalent to two convolve commands in G’MIC with a transpose of the vector:

gmic run "image.dat (0.5;0.5;0) +convolve.. .,0 transpose[1] convolve. [1],0 rm[1] rv sub"

Highly likely! Also, the padding isn’t necessary because convolve already defaults to neumann.

I am a step closer to better edge detection and satisfying my apparent obsession with it. :partying_face: @Reptorian

1 Like

With the current spiral transform script this happens on 2.6.7:

*** Error in ./fx_jr_spiral_transform/*repeat/*local/spiralbw/ *** Command 'check': Invalid argument 'if>=1 && if>=1 && isbool(0)': Undefined variable 'if' in expression 'if>=1...'.

Why? This also happened on 2.6.4 even though it never used to before on that version.

spiralbw needs at least one parameter for width (and height)! Only the second parameter and third has a default value!

gmic h spiralbw

spiralbw:

    >0,_height>0,_is_2dcoords={ 0 | 1 }

  Input a 2D rectangular spiral image with specified size.

  Default values: 'height=width' and 'is_2dcoords=0'.

  

  Example: [#1]  spiralbw 16

  

           [#2]  image.jpg spiralbw {[w,h]},1 +warp[0] [1],0 +warp[2] [1],2

Your script shows the missing parameter between spiralbw and if. Maybe the latest improvement of spiralbw got this seemingly new parameter combination!

gmic e $$fx_jr_spiral_transform

[gmic]-0./ Start G’MIC interpreter.

[gmic]-0./ repeat ! l[>] if $4 permute yxzc fi +spiralbw if $2 mirror[1] x fi if $3 mirror[1] y fi if $5 f[1] “iM-i” fi if $1 [0] f[2] “I(#0,i0#1%w,floor(i0#1/w),0)=I” else f[0] “I(i#1%w,floor(i#1/w))” fi k[0] if $4 permute yxzc fi endl done

[gmic]-0./ End G’MIC interpreter.

1 Like

Thanks for that, but now I have another problem with UW4+

#@gui UltraWarp++++ : fx_ultrawarp4plus, fx_ultrawarp4plus_preview(1)
#@gui :  note  = note("A sequence of multiple partially-randomised texture generation and image deformation filters with multi-iteration warping.")
#@gui :  note  = note("<small>This modular filter is extremely complex and its logic may not follow that which you expect. Left on its default settings, it is very likely to munge your image beyond recognition. This original version has been kept alive despite being slower than UltraWarp 2.</small>"), sep = separator()
#@gui :  0.  Recompute  = button(0)
#@gui :  sep  = separator()
#@gui :  1.  Plasma Texture [Discards Input Image]  = bool(0)
#@gui :  2.  Plasma Scale  = float(3.3,0,20)
#@gui :  3.  Plasma Alpha Channel  = bool(0)
#@gui :  sep  = separator()
#@gui :  4.  Segmentation [No Alpha Channel]  = bool(0)
#@gui :  5.  Edge Threshold  = float (5,0.01,60)
#@gui :  6.  Smoothness  = float (0,0,60)
#@gui :  sep  = separator()
#@gui :  7.  Blur  = float (0,0,30)
#@gui :  sep  = separator()
#@gui :  8.  Quadtree Pixelisation [No Alpha Channel]  = bool(0)
#@gui :  9.  Quadtree Min Precision  = int(4,2,8192)
#@gui :  10.  Quadtree Max Precision  = int(256,0,8192)
#@gui :  11.  Quadtree Min Homogeneity  = float(4.8,0,5)
#@gui :  12.  Quadtree Max Homogeneity  = float(5,0,5)
#@gui :  sep  = separator()
#@gui :  13. Noise Type  = choice(2,"Gaussian","Uniform","Salt and pepper","Poisson")
#@gui :  14. Minimum Noise  = float(0,0,8)
#@gui :  15. Maximum Noise  = float(0,0,8)
#@gui :  16. Noise Channel(s)  = choice(2,"All","RGBA [all]","RGB [all]","RGB [red]","RGB [green]","RGB [blue]","RGBA [alpha]","Linear RGB [all]","Linear RGB [red]","Linear RGB [green]","Linear RGB [blue]","YCbCr [luminance]","YCbCr [blue-red chrominances]","YCbCr [blue chrominance]","YCbCr [red chrominance]","YCbCr [green chrominance]","Lab [lightness]","Lab [ab-chrominances]","Lab [a-chrominance]","Lab [b-chrominance]","Lch [ch-chrominances]","Lch [c-chrominance]","Lch [h-chrominance]","HSV [hue]","HSV [saturation]","HSV [value]","HSI [intensity]","HSL [lightness]","CMYK [cyan]","CMYK [magenta]","CMYK [yellow]","CMYK [key]","YIQ [luma]","YIQ [chromas]")
#@gui :  sep  = separator(), note = note("<small>Warping</small>")
#@gui :  17. Warp Iterations  = int(3,0,30)
#@gui :  18. Warp Intensity  = float(3,0,10)
#@gui :  19. Warp Offset  = float(20,0,2000)
#@gui :  20. Scale to Width  = bool(1)
#@gui :  21. Scale to Height  = bool(1)
#@gui :  22. Correlated Channels  = choice("Random","Off","On")
#@gui :  23. Boundary  = choice(5,"Random","Random [non-transparent]","Transparent","Nearest","Periodic", "Mirror")
#@gui :  24. Warp Channel(s)  = choice(2,"Random","RGBA [all]","RGB [all]","RGB [red]","RGB [green]","RGB [blue]","RGBA [alpha]","Linear RGB [all]","Linear RGB [red]","Linear RGB [green]","Linear RGB [blue]","YCbCr [luminance]","YCbCr [blue-red chrominances]","YCbCr [blue chrominance]","YCbCr [red chrominance]","YCbCr [green chrominance]","Lab [lightness]","Lab [ab-chrominances]","Lab [a-chrominance]","Lab [b-chrominance]","Lch [ch-chrominances]","Lch [c-chrominance]","Lch [h-chrominance]","HSV [hue]","HSV [saturation]","HSV [value]","HSI [intensity]","HSL [lightness]","CMYK [cyan]","CMYK [magenta]","CMYK [yellow]","CMYK [key]","YIQ [luma]","YIQ [chromas]")
#@gui :  25. Random Negation  = bool(1)
#@gui :  26. Random Negation Channel(s)  = choice(2,"Random","RGBA [all]","RGB [all]","RGB [red]","RGB [green]","RGB [blue]","RGBA [alpha]","Linear RGB [all]","Linear RGB [red]","Linear RGB [green]","Linear RGB [blue]","YCbCr [luminance]","YCbCr [blue-red chrominances]","YCbCr [blue chrominance]","YCbCr [red chrominance]","YCbCr [green chrominance]","Lab [lightness]","Lab [ab-chrominances]","Lab [a-chrominance]","Lab [b-chrominance]","Lch [ch-chrominances]","Lch [c-chrominance]","Lch [h-chrominance]","HSV [hue]","HSV [saturation]","HSV [value]","HSI [intensity]","HSL [lightness]","CMYK [cyan]","CMYK [magenta]","CMYK [yellow]","CMYK [key]","YIQ [luma]","YIQ [chromas]")
#@gui :  27. Gamma Offset  = float(0.25,0,1)
#@gui :  28. Hue Offset  = float(1,0,1)
#@gui :  29. Normalise  = bool(1)
#@gui :  sep  = separator(), note = note("<small>Final HSV Scaling</small>")
#@gui :  30. Minimum Hue  = float(0,0,20)
#@gui :  31. Maximum Hue  = float(5,0,20)
#@gui :  32. Minimum Saturation  = float(0,0,20)
#@gui :  33. Maximum Saturation  = float(3,0,20)
#@gui :  34. Minimum Value  = float(0.5,0,20)
#@gui :  35. Maximum Value  = float(2,0,20)
#@gui :  note  = note("<small>Set these to their minimum values for randomisation</small>")
#@gui :  36. Hue Offset  = float(-180.01, -180.01, 180)
#@gui :  37. Saturation Offset  = float(0, -1.01, 1)
#@gui :  38. Value Offset  = float(0,-20.01,20)
#@gui :  sep  = separator(),
#@gui :  -4. Normalise  = bool(1)
#@gui :  -3. Normalisation Channel(s)  = choice(11,"All","RGBA [all]","RGB [all]","RGB [red]","RGB [green]","RGB [blue]","RGBA [alpha]","Linear RGB [all]","Linear RGB [red]","Linear RGB [green]","Linear RGB [blue]","YCbCr [luminance]","YCbCr [blue-red chrominances]","YCbCr [blue chrominance]","YCbCr [red chrominance]","YCbCr [green chrominance]","Lab [lightness]","Lab [ab-chrominances]","Lab [a-chrominance]","Lab [b-chrominance]","Lch [ch-chrominances]","Lch [c-chrominance]","Lch [h-chrominance]","HSV [hue]","HSV [saturation]","HSV [value]","HSI [intensity]","HSL [lightness]","CMYK [cyan]","CMYK [magenta]","CMYK [yellow]","CMYK [key]","YIQ [luma]","YIQ [chromas]")
#@gui :  sep  = separator(),
#@gui :  -2. UltraWarp++++ Channel(s)  = choice("All","RGBA [all]","RGB [all]","RGB [red]","RGB [green]","RGB [blue]","RGBA [alpha]","Linear RGB [all]","Linear RGB [red]","Linear RGB [green]","Linear RGB [blue]","YCbCr [luminance]","YCbCr [blue-red chrominances]","YCbCr [blue chrominance]","YCbCr [red chrominance]","YCbCr [green chrominance]","Lab [lightness]","Lab [ab-chrominances]","Lab [a-chrominance]","Lab [b-chrominance]","Lch [ch-chrominances]","Lch [c-chrominance]","Lch [h-chrominance]","HSV [hue]","HSV [saturation]","HSV [value]","HSI [intensity]","HSL [lightness]","CMYK [cyan]","CMYK [magenta]","CMYK [yellow]","CMYK [key]","YIQ [luma]","YIQ [chromas]")
#@gui :  -1. Value Action  = choice("None","Cut","Normalize")
fx_ultrawarp4plus:
hue_min={$30}
hue_max={$31}
sat_min={$32}
sat_max={$33}
val_min={$34}
val_max={$35}
j={min($hue_min,$hue_max)+(u*(max($hue_min,$hue_max)-min($hue_min,$hue_max)))}
k={min($sat_min,$sat_max)+(u*(max($sat_min,$sat_max)-min($sat_min,$sat_max)))}
l={min($val_min,$val_max)+(u*(max($val_min,$val_max)-min($val_min,$val_max)))}
if {$1}
if {$2} ch=0 else ch=2 fi
ac  "rr={round(u*255)}
gg={round(u*255)}
bb={round(u*255)}
fx_plasma 0.5,0,{$2},1,1,{$rr},{$gg},{$bb}
if {$3} to_rgba else ch=2 to_rgb fi",{$ch} fi
fx_gaussian_blur {$7},0,0,1,2,0,0
n_min=$14
n_max=$15
if $n_min>$n_max
n_min=$n_min + $n_max
n_max=$n_min - $n_max
n_min=$n_min - $n_max
fi
noise_exp={max(0,$n_min+(u*($n_max-$n_min)))}
n_amt={(2^($noise_exp-3))*$noise_exp}
if {$4} fx_segment_watershed {$5},{$6},0,2,0 fi
if {$8}
p_min={$9}
p_max={$10}
h_min={$11}
h_max={$12}
if $p_min>$p_max
p_min=$p_min + $p_max
p_max=$p_min - $p_max
p_min=$p_min - $p_max
fi
if $h_min>$h_max
h_min=$h_min + $h_max
h_max=$h_min - $h_max
h_min=$h_min - $h_max
fi
fx_noise {$n_amt},{$13},{$16},1,0
fx_quadtree 0,{max(2,round($p_min+(u*($p_max-$p_min))))},{max(0,round($h_min+(u*($h_max-$h_min))))},0,3,1.5,1,1,0
fi
fx_noise {$n_amt},{$13},{$16},1,0
f={$17}
i={$18}
m={$19}
s={$20}
v={$21}
repeat {max(0,$f)}
if {$20}
scale_x=w/10
a={((2^($18-5))*$18)*(u-0.5)*$scale_x*0.025}
else
scale_x=1
a={((2^($18-5))*$18)*(u-0.5)}
fi
if {$22}
scale_y=h/10
b={((2^($18-5))*$18)*(u-0.5)*$scale_y*0.025}
else
scale_y=1
b={((2^($18-5))*$18)*(u-0.5)}
fi
c=(u-0.5)*$m*sign($m)*$scale_x
d=(u-0.5)*$m*sign($m)*$scale_y
g={round((u*33.98)-0.49)}
h={(u-0.5)*$s*200}
o={(u-0.5)*$v*200}
if {$22==1}
e=0
elif {$22==2}
e=1
else
e={round(u)}
fi
if {$23==0}
f={round((u*2.98)-0.49)}
elif {$23==1}
f={round((u*2.98)+0.51)}
else
f={($23)-2}
fi
ac "_fx_warp_by_intensity "{$a}","{$b}","{$c}","{$d}","{$e}",0,"{$f}"",{$24},0
if {$25}
nn={round(u)}
if {$nn}
if {$26==0}
nch={round((u*33.98)-0.49)}
ac "negate",{$nch}
else
ac "negate",{$26}
fi
fi
fi
fx_adjust_colors 0,0,{$h},{$o},0,0
if {$29}
ac "n 0,255",3
fi
done
if {$36==-180.1}
hh=((u-0.5)*360)
else
hh={$36}
fi
if {$37==-8.01}
ss=((u-0.5)*2)
else
ss={$37}
fi
if {$38==-20.01}
vv=((u-0.5)*2)
else
vv={$38}
fi
fx_mix_hsv {$j},{$hh},0,{$k},{$ss},0,{$l},{$vv},0,0,2,0
if {$-2}
ac "n 0,255",{$-1}
fi
fx_ultrawarp4plus_preview:
repeat $! l[$>]
ac "fx_ultrawarp4plus ${2--3}",$-2,$-1
fx_adjust_colors 0,0,0,{(u-0.5)*200},0,0
endl done

The GUI for the GIMP plugin works fine when it’s making preview images but when I apply it to the image itself I get this:

*** Error in ./fx_ultrawarp4plus/fx_noise/ac/_apply_channels/ *** Unknown command or filename '_ac_0.45000000000000001'.

I don’t know why this error doesn’t happen in the preview and I know even less about how I can fix it since the variable whose value it’s actually reading out is nowhere near any calls toac. Also, where can I find the debug log on a Windows system?

I am guessing it is because of the following line in the stdlib. BTW, your command is way too long. I suggest that you break it into manageable parts (macros or commands) and make it have default CLI arguments so that testers like me can run it without having to type and and keep track of them. Comments would be helpful too.

_ac_$mode m _ac_precond$id:$_p m _ac_forward$id:$_f m _ac_backward$id:$_b

Hi, I get the error message

Bildschirmfoto 2019-07-03 um 22.12.12.png

The preview call is

...

ac "fx_ultrawarp4plus ${2--3}",$-2,$-1

...

The plugin is seemingly calling

fx_ultrawarp4plus $*

hence ${1–1}.

Following all parameters are shifted by 1.

Maybe you should also create a function _fx_ultrawarp4plus called with ${2–3}

fx_ultrawarp4plus:

_fx_ultrawarp4plus ${2–3}

_fx_ultrawarp4plus:

fx_ultrawarp4plus_preview:

_fx_ultrawarp4plus ${2–1}

By the way, for this type of random image generation, it might be helpful to have at least one parameter configuration with expectable output for testing purposes! All parameters shifted by one deliver possibly acceptable output too!