Trying to make my 1st "pipeline filter"

Hello there,

i’ve been playing with Gmic for some time now, trying to figure out how the commands work and what they do. I’ve sure learned a lot these past days, even if i’ve known Gimp+Gmic for (10?) years now… I’ve always been a math amputee so i can’t really call my stuff a filter or a script though. Anyway , thanks for creating Gmic :slight_smile:

So i decided to write a (really) huge pipeline during the pandemic, then converted it to a custom command a few weeks ago and then to a GUI filter, etc. Before that is was just using the commandline which was kinda trial and error…
Finally rewrote the damn thing because it was kinda slow, and now i’m just adding features and testing. It seems endless, really, but it’s fun :slight_smile: So i created a bash script to launch the command with random params… gave me weird but interesting stuff!
BTW, how do you decide what parameters to add to the GUI? Ihave so many already…

Right now i’m trying to figure out how to “tame” the preview in Gmic-qt.
How can i make the zoom work for instance? Each time i zoom in the picture, it relaunches the command and then zooms back to full view. Is it possible to “freeze” the results of the preview so i can zoom in and see the details?

Thanks

BTW, here’s what it does so far (All originals from unsplash : one two three ) :



2 Likes

I do have some Python script to reduce number of trials required for GUI filter developments. Things like:

  1. Numbering parameters. This makes it easier to read your code and follow along GUI parameters. This Python script also removes numbers for GUI code.
  2. Shifting numberical arguments $n. This allows me to shift every single arguments.

Both of these enables me to make very complex GUI filters. One of them in fact has over 1000 parameters, and a lot of it are hidden away behind dynamic GUI codes.

I add based on the options provided by the CLI filter first, then see how I can convert into GUI filter. For me to decide what parameters I should add, I think of how I may be able to achieve that, and if it is on the scope of said filter, then I try to implement parameter.

That depends on whether you’re using full preview or not. Read this for a bit.

#    '#@gui Command name : command, preview_command (zoom_factor)[*|+] [: default_input_mode]
#    '#@gui : parameter1 = typedef(arguments1...), parameter2 = typedef(arguments2...)'
#    '#@gui : parameter3 = typedef(arguments3...),
#
#   where :
#
#      'command' is the G'MIC command name called to process the image.
#
#      'preview_command' is the G'MIC command name called to process the preview.
#
#           Note that you can optionally specify a float-valued factor>=0 between parentheses at the end of
#           the 'preview_command' to force the default zoom factor used by the preview for this filter.
#           Use (0) for a 1:1 preview, (1) for previewing the whole image, (2) for 1/2 image and so on...
#           You can put an additional '+' sign after the parenthesis to specify the rendered preview
#           is still accurate for different zoom factors. Use '*' instead to tell the plug-in that the preview filter
#           must get the entire image rather than a thumbnail.
#
#
#      'default_input_mode' set the default input mode for that filter. It can be
#        { x=none | .=active (default) | *=all | +=active & below | -=active & above | v=all visible | i=all invisible }
#
#      'parameter = typedef' tells about the names, types and default values of the filter parameters.
#
#           'typedef' can be :
#
#      _ 'bool(default_value={ 0 | 1 | false | true })':
#          Add a boolean parameter (0 or 1) (as a checkbutton).
#
#      _ 'button(_alignment)':
#          Add a boolean parameter (0 or 1) (as a button).
#
#      _ 'choice(_default_index,Choice0,..,ChoiceN)':
#          Add a integer parameter (as a combobox).
#
#      _ 'color(R,_G,_B,_A)':
#          Add R,G,B[,A] parameters (as a colorchooser).
#
#      _ 'point(_X,_Y,_removable={ -1 | 0 | 1 },_burst={ 0 | 1 },_R,_G,_B,_[-]A,_radius[%])':
#          Add X,Y parameters (as a moveable point over the preview).
#
#      _ 'file[_in,_out](_default_filename)':
#          Add a filename parameter (as a filechooser).
#
#      _ 'float(default_value,min_value,max_value)':
#          Add a float-valued parameter (as a float slider).
#
#      _ 'folder(_default_foldername)':
#          Add a foldername parameter (as a folderchooser).
#
#      _ 'int(default_value,min_value,max_value)':
#          Add a integer parameter (as an integer slider).
#
#      _ 'link(_alignment,_label,URL)':
#          Display a URL (do not add a parameter).
#
#      _ 'note(_label)':
#          Display a label (do not add a parameter).
#
#      _ 'text(_is_multiline={ 0 | 1 },_default text)':
#          Add a single or multi-line text parameter (as a text entry).
#
#      _ 'separator()':
#          Display an horizontal separator (do not add a parameter).
#
#      _ 'value(value)':
#          Add a pre-defined value parameter (not displayed).
#
#   Type separators '()' can be replaced by '[]' or '{}' if necessary (for instance if parentheses are required in
#   an argument of the typedef, e.g in a text). You can also replace 'typedef' by '_typedef' to tell the plug-in not
#   being responsive, i.e not to update the image preview when the corresponding parameter is modified.
#   After the closing separator, you may specify a 'visibility state' character for the parameter, which can be
#   { _0=Hidden | _1=Grayed-out | _2=Visible (default) }, opt. followed by a propagation character that tells
#   if this visibility state must be propagated to neighboring non-valued interface widgets
#   (s.a. separator(), link() or note()).
#   This propagation character can be:
#   { '+'=propagate forward | '-'=propagate backward | '*'=propagate in both directions }.
#
#   Use '_none_' as a special command or preview_command to tell the plug-in that the entry requires no G'MIC call.
#
#   A G'MIC command can set new values for each filter parameter, through the status (see command ''status'').
#   To do so, the returned status must follow the syntax :
#   '{params1}{params2}{..}{paramsN}' where N must be exactly equal to the number of parameters
#   for the current filter. Optionally, you can append to each {param} its visibility state suffix ( e.g: {param}_1 ).
#
#   A G'MIC command can also specify the output blending mode, the opacity and the position of each of the output image
#   (i.e. layer in the plug-in). To do so, set the image name to something like:
#   'mode(grainmerge),opacity(50),pos(30,50),name(name)'.
#
#     - Blending mode name should be the same as the argument of the 'blend' command.
#     - Opacity is a float number in [0,100].
#     - X and Y positions are integers.
#     - 'name' is the layer name.
#
#   Pre-defined plug-in variables:
#
#   - _preview_width: Width of the preview image.
#   - _preview_height: Height of the preview image.
#   - _preview_area_width: Width of the preview widget area.
#   - _preview_area_height: Height of the preview widget area.
#   - _preview_x0: X-coordinate of the upper-left corner of the preview (expressed in the image space).
#   - _preview_y0: Y-coordinate of the upper-left corner of the preview (exressed in the image space).
#   - _preview_x1: X-coordinate of the lower-right corner of the preview (expressed in the image space).
#   - _preview_y1: Y-coordinate of the lower-right corner of the preview (expressed in the image space).
#   - _persistent : Variable that is shared between successive calls to the G'MIC interpreter, for a single filter.
#
#   Values of variables $_preview[x/y][0/1] vary only when preview mode is set to * (full preview).

Source: G’MIC stdlib

I think you would need to use (0) in zoom_factor. I just play around with it until I’m satisfied.

Anyway, I think your filters looks fun. Hope to see more from you.

Hi @prawnsushi another g’mic enthusiast is good news :slight_smile:

I have very little time right now, so I’ll just put a link to the filter template file which might help with gui stuff. Hopefully I’ll get back later with more, unless somebody beats me to it!

Hi @Reptorian

Thank you for the quick replies!

Yes i have seen your post about it. For now i only have 33 parameters in the GUI so i decided to go the easy way as demonstrated by @David_Tschumperle :
param1,param2,param3,...=${1-33}
This way, it is indeed very easy to insert params anywhere in between. All my params are named. I wouldn’t be able to remember what $21 represents anyway…
I’ll try to use your script if i ever Hit the 100 params!

I just hope you don’t intend to put them all in the GUI hahaha. Unless you can fold/unfold or hide/unhide them from the GUI. Actually i was wondering if the reset button could allow for a selection of the params to reset to default. Would be nice for filter with lots of params.

Quite like what i did actually since this was a long CLI pipeline before turning to GUI for testing the values. But a bash script with random values is nice too. Found some effects/styles i probably wouldn’t have thought of otherwise. Not perfect though, but that’s a start. I even added a text command to write the params on the pictures, along with a txt file if i ever want to reproduce the picture.

Thanks, never saw that file… Will be way easier than reading the GmicUpdate file hahaha.

Yes, i was using zoom factor (1). I switched to (0) but then the preview was wrong. Other values didn’t help either. I switched back to (1) and probably won’t bother to wait for preview anymore. It take roughly 13 seconds to apply the filter to a picture, downsized to a 2000x2000 box. The pics i uploaded were downsized too then upscaled. I’ll probably switch to dcci later but it’s gonna slow things down. Better make it optional.
Here is what it looks like for now (default settings):

Thanks, glad you like it. I hope i’ll have other ideas later too!

@garagecoder Thanks, this will help a lot too!
Right now what puzzles me is this :
gui_split_preview "jdoe_toyfilter ${1-2}",${-3--1}
Mine is :
gui_split_preview "watergmicB ${^0}",${-1}
Changing ^0 breaks the preview immediately. I guess it’s the number of params (all but $0)? 1-33 works.

Changing $-1 breaks the preview when i move the slider for my penultimate parameter… the template doesn’t explain anything on this. :man_shrugging:

Anyway, thank you both :wink:

At a guess, you possibly need to add some more gui parameters - if you look at the last of the example params, it has #@gui : sep = separator(), Preview Type = choice("Full"...

The idea is to send all the params your filter needs only to your command, then the last params for preview control to the gui_split_preview command. I don’t remember if this is documented, but if not it’s something obviously needed!

So it’s like:
gui_split_preview "jdoe_toyfilter ${<gui params for your filter>}",${<gui params to control the preview>}

You can hide/unhide them via filter effect code.

For example, in this case:


u "{"$_hsl_h"}"\
"{"$_hsl_s"}"\
"{"$_hsl_l"}"\
"{$4}"\
"{$5}"\
"{"$_rgb_0_r","$_rgb_0_g","$_rgb_0_b"}"\
"{"$_rgb_1_r","$_rgb_1_g","$_rgb_1_b"}"\
"{"$_rgb_2_r","$_rgb_2_g","$_rgb_2_b"}_"{3<$num_of_col?2}\
"{"$_rgb_3_r","$_rgb_3_g","$_rgb_3_b"}_"{4<$num_of_col?2}\
"{"$_rgb_4_r","$_rgb_4_g","$_rgb_4_b"}_"{5<$num_of_col?2}\
"{"$_rgb_5_r","$_rgb_5_g","$_rgb_5_b"}_"{6<$num_of_col?2}\
"{"$_point_x_0","$_point_y_0"}"\
"{$26}"\
"{$27}"\

The $_hsl_h will change the first parameter to the value of $_hsl_h` There’s _rgb_1… and so forth, and they will change the color to be used in GUI. Next to it, there’s _ and then theres {}. The bracket means math evaluator. The result next to _ defines its visibility state. 0,1,2 are all valid numbers. 0 means invisible, 1 means grayed-out and visible, and 2 means changeable and visible.

This is more of a very advanced subject though.

Right now what puzzles me is this :
gui_split_preview "jdoe_toyfilter ${1-2}",${-3--1}

gui_split_preview uses a string and treats it as a evaluator code for use inside gmic. ${1-2} means to use $1,$2. ${-3--1} means last three variables you assigned to the filter. -1 is the last variable. In the case of GUI code, they’re attributed to preview type and point location.

Your example is not valid code. The valid would be:

gui_split_preview "watergmicB $*",${-3--1}

$* means all arguments provided by the user. ${-3--1} means $-3,$-2,$-1 which means last third variable to last first variable.

There’s one thing that can help, using full-size preview, then cropping according to preview variables which can be found in G’MIC stdlib. You may crop the image, and then do processing. Anyway, that is an advanced subject too, actually pretty advanced to work with full-size preview.

Hello, yes that’s it. I added one param ( the split line) to the GUI and this works fine now. (I think I forgot to turn my brains on, I was reading this as “- 3 - - 1” instead of “from -3 to -1”… Damn negative numbers. I used them a lot before using “.”, " …", etc.)

I’ll try to hide the split values next time, and maybe deactivate preview refresh on some sliders. And then maybe cropping. Not in a hurry though. Thanks!

I wonder how’s thing holding up for you. Progress?

Hi,

Well it’s progressing slowly but it’s usable. I spend most of the time looking at the command reference pages and testing things.

2 Likes

Hello,

just posting the code for this so people can play with it. I’m curious what you can do with it.

I think it’s kinda slow and i’m trying to make it faster but i don’t have enough knowledge to do so… Anyway i also like the output for low resolutions (around 1000px or 1500px)

Also i don’t know how i can make broader lines for the sketch part, it’s too thin when using larger resolutions.

Here goes (sorry for bad code heh)

Code
#@gui WaterGmicB : watergmicB, watergmic_previewB(1)*
#@gui : note = note("<small>Author: <i><a href="http://prawnsushi.free.fr">Prawnsushi</i></a>.      Latest Update: <i>2023/14/03</i>.</small>")
#@gui : sep = separator()
#@gui : Write settings on picture = bool(0)
#@gui : note = note("<small>Use original input image resolution or choose processing resolution.\nHigher Res is slower and not always better. </small>")
#@gui : Original Resolution = bool(0)
#@gui : Processing Resolution = int(1000,500,5000)
#@gui : Garagecoder's DCCI2x rescale (Post) = int(0,0,5)
#@gui : sep = separator()
#@gui : Pre-Process = bool(1)
#@gui : - Sharpening = int(0,0,500)
#@gui : - Blur = float(0,0,10)
#@gui : - Local normalization = float(0.5,0.3,3)
#@gui : Sloppiness = bool(1)
#@gui : - Distort = float(3,0,20)
#@gui : - Blur = float(3,0,50)
#@gui : - Blend Mode = choice(13,"add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation","screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor")
#@gui : - Strength = float(0.5,0.0,1.0)
#@gui : sep = separator()
#@gui : Watering = bool(1)
#@gui : - Smoothing = int(12,0,40)
#@gui : - Iterations = int(1,0,10)
#@gui : Fuzzy Frame Size = int(30,0,350)
#@gui : - Frame Blur = int(20,0,150)
#@gui : - Frame Strentgh = float(0.5,0,5)
#@gui : Plasma Seed = int(-1,-1,9999999)
#@gui : - Plasma Saturation = int(-100,-100,100)
#@gui : - Blend Mode = choice(23,"add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation",screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor")
#@gui : - Plasma Strength = float(0.5,0,1)
#@gui : sep = separator()
#@gui : Cracks = bool(1)
#@gui : Sharpening = int(150,0,500)
#@gui : - Shock Filter = int(1,0,1)
#@gui : Light1(0 means all off) = float(0.15,0,1)
#@gui : - Light2 = float(0.02,0,1)
#@gui : - Light3 = float(0.02,0,1)
#@gui : sep = separator()
#@gui : Sketch = bool(1)
#@gui : - Likeness = int(25,0,30)
#@gui : - Threshold Min = int(0,0,255)
#@gui : - Threshold Max = int(20,0,255)
#@gui : - Sketch strength = float(1,0,1)
#@gui : --- Messy lines = float(0.9,0,1)
#@gui : - Blend Mode = choice(22,"add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation",screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor")
#@gui : note = note("<small>Setting Sktech Strength to 0 disables Messy lines too.\n Messy lines uses <Breaks> by David Tschumperlé.</small>")
#@gui : Noise = float(3,0,6)
#@gui : Canvas = float(0.3,0,1)
#@gui : sep = separator()
#@gui : Post-Process = bool(1)
#@gui : Mix Original Hue/Sat = float(0.5,0,1)
#@gui : Brightness = float(0,-100,100)
#@gui : Contrast = float(0,-100,100)
#@gui : Gamma = float(0,-100,100)
#@gui : Hue = float(0,-100,100)
#@gui : Saturation = float(0,-100,100)
#@gui : sep = separator()
#@gui : Preview Type = choice("Full","Forward Horizontal","Forward Vertical","Backward Horizontal","Backward Vertical","Duplicate Top","Duplicate Left","Duplicate Bottom","Duplicate Right","Duplicate Horizontal","Duplicate Vertical","Checkered","Checkered Inverse")
#@gui :Preview Split=point(50,50,0,0,200,200,200,0,10)_0
#@gui : sep = separator()

watergmicB :

com,__origres,__procres,dccires,__bst,__bstsharp,_bstblur,__locnorm,__filt,__dist,__distblur,__distmerge,__diststr,__wc,__bilsize,__bilrep,__fuzz,__fuzzblur,__fuzstr,__plsmseed,__plsmsat,__plasmerge,__plastr,\
__cracks,__sckrad,__sck,__lgtone,__lgttwo,__lgthree,__sketch,__sklike,__cutmin,__cutmax,__linestr,__brkstr,__skmerge,__noistr,cnvs,__post,__huestr,__bri,__con,__gam,__hue,__sat=${1-45}


m "BlendMode : $""=__mode" BlendMode "add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation","screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor","error"

m "BlendModeP : $""=__modep" BlendModeP "add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation","screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor","error"


m "BlendModeL : $""=__model" BlendModeL "add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation","screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor","error"

#~ to_rgb
normalize 0,255
nm[0] ORIG
__ORIGW={0,w}
__ORIGH={0,h}

if !$__origres
	__res=$__procres,$__procres
	rr2d[ORIG] $__res,0,6
fi

if $__bst
blur $_bstblur sharpen $__bstsharp normalize_local $__locnorm,$__locnorm
fi

[ORIG] nm. REND

if $__filt
[ORIG] nm. FILT
	local[FILT]
		repeat 3
			apc "deform $__dist blur $__distblur"
		done
	done
blend[REND,FILT] ${__mode{$__distmerge+1}},$__diststr
normalize[REND] 0,255
fi

if $__wc
	if $__plastr>0
		[ORIG] nm. PLAS
			local[PLAS]
				if $__plsmseed>-1
					srand $__plsmseed
				fi
				#~ plasma 1,2,2
				plasma 1,2,5
				adjust_colors 0,0,0,0,$__plsmsat
			done
		blend[REND,PLAS] ${__modep{$__plasmerge+1}},$__plastr
	fi
fi

if $__wc
	if $__fuzz>0
	[ORIG] nm. FUZZ
		local[FUZZ]
			fill_color 0,0,0
			spread {$__fuzz/2},{$__fuzz/2},0
			negate
			frame_fuzzy $__fuzz
			blur $__fuzzblur,0
			deform $__fuzz
			spread {$__fuzz/2},{$__fuzz/2}
			spread 10
			split c rm. . negate.  append c
				if $__fuzstr!=1
					mul $__fuzstr
				fi
		done
	blend_median[REND,FUZZ]
	channels 0,2
	normalize[REND] 0,255
	fi
fi


local[REND]
	if $__cracks
		if $__sckrad>0
		repeat 3
			deform 1.5 sharpen $__sckrad,$__sck dilate_circ 1.5 sharpen $__sckrad,$__sck
		done
		fi

		if $__lgtone>0
		repeat 3
			fx_light_relief $__lgtone,$__lgttwo,$__lgthree,0,0.2,50,50,20,0.084,0,0 
			blur 2 erode_circ 3 sharpen $__sckrad
		done
		fi
	fi

	if $__wc
		repeat $__bilrep
			deform 0.3 sharpen 80,0,10,10 bilateral $__bilsize,$__bilsize,$__bilsize,$__bilsize
			#~ deform 0.3 sharpen 80,0,10,10 rolling_guidance $__bilsize,$__bilsize,0
		done
		sharpen 80,0,10,10 sharpen 50 normalize 0,255
	fi
done

if $__post
	if $__huestr>0
		[ORIG] nm. HUE
		[ORIG] nm. SAT
		move[ORIG] -1
		blend[HUE,REND] hue,$__huestr
		blend[SAT,REND] saturation,{$__huestr/3}
	fi
fi

if $__sketch
	if $__linestr>0
	[ORIG] nm. LINE
		local[LINE]
			lw={LINE,w}
			deform 1.5 rolling_guidance {31-$__sklike},10,0.5
			gradient_norm negate
				if $__brkstr>0
					+fx_breaks. 0,5,30,0,3
					blend[-1,-2,LINE] multiply,$__brkstr
				fi
			#~ equalize. 100,$__cutmin,$__cutmax d
			normalize. $__cutmin,$__cutmax
			sharpen. 100
			spread. 0.7
		done

	blend[LINE,REND] ${__model{$__skmerge+1}},$__linestr
	fi
fi

normalize[REND] 0,255
keep[REND]

if $__post
	adjust_colors[REND] $__bri,$__con,$__gam,$__hue,$__sat
fi

if $dccires>0
	repeat $dccires
		fx_scale_dcci2x[REND] 1.15,5,1
	done
fi

if $__sketch
	if $__noistr>0 fx_noise $__noistr,0,11,1,0,50,50 fi

	# canvas effect
	if $cnvs>0
		+fill_color 255,255,255
		noise. 1000,2 to_gray.
		. .
		parallel " repeat 20 blur_x. 10 sharpen. 5  spread. 0.7 deform. 0.5 done ","
		 repeat 20 blur_y.. 10 sharpen.. 5  spread.. 0.7 deform.. 0.5 done "
		*. .. 
		n 0,255 
		+gradient. xy,1 -a[-2,-1] c 
		*. {$cnvs/100}
		warp[REND] [-1],3,1,1,1
	fi
fi

keep[REND]

if $com
	RENDW={0,w}
	RENDH={0,h}
	expand_y 35,0
	shift 0,35
	text "${1-45}",10,30,12,1,255
	text ${__mode{$__distmerge+1}}" "${__modep{$__plasmerge+1}}" "${__model{$__skmerge+1}},10,50,20,1,255
fi

watergmic_previewB :
gui_split_preview "watergmicB $*",${-3--1}
2 Likes

I get an error about “undefined label LINE”, but that could be something I did wrong. Will have more time to investigate at the weekend…

I have been getting weird errors with 3.2.2 too. I think this works fine with 3.2.1. I’ll see to that later too.

mmm It should be created line 177: [ORIG] nm. LINE

Also, i forgot to remove lw={LINE,w} which is not used anymore.

My version is 3.2.0 on Manjaro

It might be rolling_guidance renaming the image. It was fixed a few days ago. Try running gmic -update?

That has fixed it indeed, thanks. The output is very “organic” looking, well done! My only (minor) complaint is processing time makes it tricky to tweak correctly, but this could just be a case of get-a-faster-computer.

Ah thanks, quite a nice word to hear! I guess that was the goal?

Yes, imagine poor me when I started this as a one liner on the command line, not knowing much about gmic functions and filters… Lots of painting in the dark.
Also, that’s the reason I added the " processing resolution" slider. I was tired of waiting. And then I added all those little bypass checkboxes, and most sliders are bypassed if you set them to zero. So if you want you can go step by step.

And now I’m searching how to make it faster, I tried “parallel” but it breaks with frame_fuzzy…

Also, how should I add presets (buttons?) and have the sliders reflect the settings? Like a few predefined params that look good and different enough. Or maybe stuff like “show only lineart” etc.?
Well, so many things to learn.

Thanks for testing, you may be the only one hahaha :wink:

Taken from the template filter file:

#   A G'MIC command can set new values for each filter parameter, through the status (see command 'status').
#   To do so, the returned status must follow the syntax :
#   '{params1}{params2}{..}{paramsN}' where N must be exactly equal to the number of parameters
#   for the current filter. Optionnally, you can append to each {param} its visibility state suffix ( e.g: {param}_1 ).

Which more or less means your command must end with the status command (shortcut u), with correct params. I personally find it a bit painstaking to do, mainly because the string/macro handling can be hard to grasp. My usual method is to look for an existing filter and see what it does.

I think there’s a significant number of “lurkers” who never post, don’t be so sure!

Hard to grasp indeed…
I could make presets work but couldn’t make the status command work (sliders don’t refresh) … At some point it sorta worked : i couldn’t use the checkmarks anymore, they would uncheck immediately hahaha.
I looked at other scripts (@Reptorian 's Attractor for example) that have working status refresh but couldn’t replicate it and have it work. I’ll try to create a dummy filter to test this, or just drop it.

EDIT : I got it working a few minutes later: i removed “gui_split_preview” and status update started working. Got 2 presets working but now i need to find out how to have a “no preset” dropdown entry (it doesn’t work for now). I probably have to make a preset with the default params i guess.

2 Likes

Hi,
I don’t know why but something weird is happening with the presets…
Example :
select filter → OK, shows default settings preview
preset 1 → OK, shows preview
preset 2 → shows preview but then switches to previous preset
preset 3 → shows preview but then switches to preset 1 ?
preset 4 → OK, shows preview

I only have a if $preset==1... elif 2... elif 3... elif 4 ... fi structure and this doesn’t happen if i remove the “u” command to update the GUI.
It happens wether i put the status command in the preview script or the main script.

Can someone help me figure out what’s happening? Thanks.

Here is the code:

Code
#@gui WaterGmicB : watergmicB, watergmic_previewB(0)
#@gui : note = note("<small>Author: <i><a href="http://prawnsushi.free.fr">Prawnsushi</i></a>.      Latest Update: <i>2023/14/03</i>.</small>")
#@gui : sep = separator()
#@gui : Write settings on picture = bool(0)
#@gui : note = note("<small>Use original input image resolution or choose processing resolution.\nHigher Res is slower and not always better. </small>")
#@gui : Original Resolution = bool(1)
#@gui : Processing Resolution = int(1000,500,5000)
#@gui : Garagecoder's DCCI2x rescale (Post) = int(0,0,5)
#@gui : sep = separator()
#@gui : note = note("<small>Will revert to None after application so settings can be modified. </small>")
#@gui : - Presets = choice(0,"None","1 - Soft","2 - Cracked","3 - Black","4 - Faded Black")
#@gui : sep = separator()
#@gui : Pre-Process = bool(1)
#@gui : - Sharpening = int(0,0,500)
#@gui : - Blur = float(0,0,10)
#@gui : - Local normalization = float(0.5,0.3,3)
#@gui : Sloppiness = bool(1)
#@gui : - Distort = float(3,0,20)
#@gui : - Blur = float(3,0,50)
#@gui : - Blend Mode = choice(13,"add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation","screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor")
#@gui : - Strength = float(0.5,0.0,1.0)
#@gui : sep = separator()
#@gui : Watering = bool(1)
#@gui : - Smoothing = int(12,0,40)
#@gui : - Iterations = int(1,0,10)
#@gui : Fuzzy Frame Size = int(30,0,350)
#@gui : - Frame Blur = int(20,0,150)
#@gui : - Frame Strentgh = float(0.5,0,5)
#@gui : Plasma Seed = int(-1,-1,9999999)
#@gui : - Plasma Saturation = int(-100,-100,100)
#@gui : - Blend Mode = choice(23,"add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation",screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor")
#@gui : - Plasma Strength = float(0.3,0,1)
#@gui : sep = separator()
#@gui : Cracks = bool(1)
#@gui : Sharpening = int(150,0,500)
#@gui : - Shock Filter = int(1,0,1)
#@gui : Light Relief (0 means all off) = float(0.15,0,1)
#@gui : - Light2 = float(0.02,0,1)
#@gui : - Light3 = float(0.02,0,1)
#@gui : sep = separator()
#@gui : Sketch = bool(1)
#@gui : - Likeness = int(25,0,30)
#@gui : - Threshold Min = int(0,0,255)
#@gui : - Threshold Max = int(20,0,255)
#@gui : - Sketch strength = float(1,0,1)
#@gui : --- Messy lines = float(0.9,0,1)
#@gui : - Blend Mode = choice(22,"add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation",screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor")
#@gui : note = note("<small>Setting Sktech Strength to 0 disables Messy lines too.\n Messy lines uses 'Breaks' by David Tschumperlé.</small>")
#@gui : Noise = float(3,0,6)
#@gui : Canvas = float(0.3,0,1)
#@gui : sep = separator()
#@gui : Post-Process = bool(1)
#@gui : Mix Original Hue/Sat = float(0.5,0,1)
#@gui : Brightness = float(0,-100,100)
#@gui : Contrast = float(0,-100,100)
#@gui : Gamma = float(0,-100,100)
#@gui : Hue = float(0,-100,100)
#@gui : Saturation = float(0,-100,100)
#@gui : sep = separator()

watergmicB :

com,__origres,__procres,dccires,preset,__bst,__bstsharp,__bstblur,__locnorm,__filt,__dist,__distblur,__distmerge,__diststr,__wc,__bilsize,__bilrep,__fuzz,__fuzzblur,__fuzstr,__plsmseed,__plsmsat,__plasmerge,__plastr,__cracks,__sckrad,__sck,__lgtone,__lgttwo,__lgthree,__sketch,__sklike,__cutmin,__cutmax,__linestr,__brkstr,__skmerge,__noistr,cnvs,__post,__huestr,__bri,__con,__gam,__hue,__sat=$*

if $preset==1
com,__origres,__procres,dccires,preset,__bst,__bstsharp,__bstblur,__locnorm,__filt,__dist,__distblur,__distmerge,__diststr,__wc,__bilsize,__bilrep,__fuzz,__fuzzblur,__fuzstr,__plsmseed,__plsmsat,__plasmerge,__plastr,__cracks,__sckrad,__sck,__lgtone,__lgttwo,__lgthree,__sketch,__sklike,__cutmin,__cutmax,__linestr,__brkstr,__skmerge,__noistr,cnvs,__post,__huestr,__bri,__con,__gam,__hue,__sat=\
0,1,1000,0,1,1,0,0,3,1,20,10,10,0.5,1,12,2,127,42,0.365,-1,2,11,0.282,1,1,1,0.01,0.02,0.02,1,29,0,70,0.455,1,20,4,0.2,1,1,0,0,9,0,-7.2
elif $preset==2	com,__origres,__procres,dccires,preset,__bst,__bstsharp,__bstblur,__locnorm,__filt,__dist,__distblur,__distmerge,__diststr,__wc,__bilsize,__bilrep,__fuzz,__fuzzblur,__fuzstr,__plsmseed,__plsmsat,__plasmerge,__plastr,__cracks,__sckrad,__sck,__lgtone,__lgttwo,__lgthree,__sketch,__sklike,__cutmin,__cutmax,__linestr,__brkstr,__skmerge,__noistr,cnvs,__post,__huestr,__bri,__con,__gam,__hue,__sat=\
0,1,1000,0,2,0,0,0,0.3,1,3,3,13,0.5,1,12,1,0,20,0.5,-1,-100,37,0.755,1,500,1,0.027,0.02,0.02,1,25,0,220,1,0.9,22,6,0.3,1,1,0,0,31,0,0
elif $preset==3	com,__origres,__procres,dccires,preset,__bst,__bstsharp,__bstblur,__locnorm,__filt,__dist,__distblur,__distmerge,__diststr,__wc,__bilsize,__bilrep,__fuzz,__fuzzblur,__fuzstr,__plsmseed,__plsmsat,__plasmerge,__plastr,__cracks,__sckrad,__sck,__lgtone,__lgttwo,__lgthree,__sketch,__sklike,__cutmin,__cutmax,__linestr,__brkstr,__skmerge,__noistr,cnvs,__post,__huestr,__bri,__con,__gam,__hue,__sat=\
0,1,1000,0,3,1,0,0,2.3736,1,3,3,13,0.5,1,23,2,30,20,0.5,-1,-100,23,0.5,1,0,1,0.01,0.02,0.02,1,28,0,20,1,0.9,22,6,0,1,0,0,0,0,0,-100
elif $preset==4
com,__origres,__procres,dccires,preset,__bst,__bstsharp,__bstblur,__locnorm,__filt,__dist,__distblur,__distmerge,__diststr,__wc,__bilsize,__bilrep,__fuzz,__fuzzblur,__fuzstr,__plsmseed,__plsmsat,__plasmerge,__plastr,__cracks,__sckrad,__sck,__lgtone,__lgttwo,__lgthree,__sketch,__sklike,__cutmin,__cutmax,__linestr,__brkstr,__skmerge,__noistr,cnvs,__post,__huestr,__bri,__con,__gam,__hue,__sat=\
0,1,1000,0,4,1,308,0,2.3736,1,3,3,0,0.5,1,23,2,350,1,0.5,-1,100,10,1,1,0,1,0.2,0.02,0.02,1,29,0,9,0.9,1,22,6,0.12,1,0,0,0,13.4,0,-100
fi



preset=0

m "BlendMode : $""=__mode" BlendMode "add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation","screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor","error"

m "BlendModeP : $""=__modep" BlendModeP "add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation","screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor","error"

m "BlendModeL : $""=__model" BlendModeL "add","and","average","blue","burn","darken","difference","divide","dodge","exclusion","grainextract","grainmerge","green","hardlight","hardmix","hue","interpolation","lighten","lightness","linearburn","linearlight","luminance","multiply","negation","or","overlay","pinlight","red","reflect","saturation","screen","shapeaverage","softburn","softdodge","softlight","stamp","subtract","value","vividlight","xor","error"



#~ to_rgb
normalize 0,255
nm[0] ORIG
__ORIGW={0,w}
__ORIGH={0,h}

if !$__origres
	__res=$__procres,$__procres
	rr2d[ORIG] $__res,0,6
fi


if $__bst
	blur $__bstblur sharpen $__bstsharp normalize_local $__locnorm,$__locnorm
fi

[ORIG] nm. REND



if $__filt
[ORIG] nm. FILT
	local[FILT]
			apc "deform $__dist blur $__distblur"
	done
blend[REND,FILT] ${__mode{$__distmerge+1}},$__diststr
n[REND] 0,255
fi

if $__wc
	if $__plastr>0
	[ORIG] nm. PLAS
		local[PLAS]
			if $__plsmseed>-1
				srand $__plsmseed
			fi
			plasma 1,2,5
			adjust_colors 0,0,0,0,$__plsmsat
		done
	blend[REND,PLAS] ${__modep{$__plasmerge+1}},$__plastr
	fi
fi

if $__wc
	if $__fuzz>0
	[ORIG] nm. FUZZ
		local[FUZZ]
			fill_color 0,0,0
			spread {$__fuzz/2},{$__fuzz/2},0
			negate
			frame_fuzzy $__fuzz
			blur $__fuzzblur,0
			deform $__fuzz
			spread {$__fuzz/2},{$__fuzz/2}
			spread 10
			split c rm. . negate.  append c
				if $__fuzstr!=1
					mul $__fuzstr
				fi
		done
	blend_median[REND,FUZZ]
	channels 0,2
	normalize[REND] 0,255
	fi
fi


local[REND]
	if $__cracks
		if $__sckrad>0
			deform 1.5 sharpen $__sckrad,$__sck dilate_circ 1.5 sharpen $__sckrad,$__sck
		fi

		if $__lgtone>0
			repeat 3
				fx_light_relief $__lgtone,$__lgttwo,$__lgthree,0,0.2,50,50,20,0.084,0,0 blur 2 erode_circ 3 sharpen $__sckrad
			done
		fi
	fi

	if $__wc
		repeat $__bilrep
			deform 0.3 sharpen 80,0,10,10 bilateral $__bilsize,$__bilsize,$__bilsize,$__bilsize
		done
		sharpen 80,0,10,10 sharpen 50 normalize 0,255
	fi
done

if $__post
	if $__huestr>0
		[ORIG] nm. HUE
		[ORIG] nm. SAT
		move[ORIG] -1
		blend[HUE,REND] hue,$__huestr
		blend[SAT,REND] saturation,{$__huestr/3}
	fi
fi

if $__sketch
	if $__linestr>0
	[ORIG] nm. LINE
		local[LINE]
			deform 1.5 rolling_guidance {31-$__sklike},10,0.5
			gradient_norm negate
				if $__brkstr>0
					+fx_breaks. 0,5,30,0,3
					blend[-1,-2,LINE] multiply,$__brkstr
				fi
			normalize. $__cutmin,$__cutmax
			sharpen. 100
			spread. 0.7
		done

	blend[LINE,REND] ${__model{$__skmerge+1}},$__linestr
	fi
fi

normalize[REND] 0,255
keep[REND]

if $__post
	adjust_colors[REND] $__bri,$__con,$__gam,$__hue,$__sat
fi

if $dccires>0
	repeat $dccires
		fx_scale_dcci2x[REND] 1.15,5,1
	done
fi

if $__sketch
	if $__noistr>0 fx_noise $__noistr,0,11,1,0,50,50 fi
	# canvas effect
	if $cnvs>0
		+fc 255,255,255
		noise. 1000,2 to_gray.
		. .
		parallel " repeat 20 blur_x. 10 sharpen. 5  spread. 0.7 deform. 0.5 done ","
		 repeat 20 blur_y.. 10 sharpen.. 5  spread.. 0.7 deform.. 0.5 done "
		*. ..
	        keep[0,-1]
		n. 0,255
		+gradient. xy,1 -a[-2,-1] c
		*. {$cnvs/100}
		warp[REND] [-1],3,1,1,1
	fi
fi

keep[REND]

if $com
	RENDW={0,w}
	RENDH={0,h}
	expand_y 35,0
	shift 0,35
	text "${1-45}",10,30,12,1,255
	text ${__mode{$__distmerge+1}}" "${__modep{$__plasmerge+1}}" "${__model{$__skmerge+1}},10,50,20,1,255
fi

u "{"$com"}""{"$__origres"}""{"$__procres"}{"$dccires"}""{"0"}""{"$__bst"}""{"$__bstsharp"}""{"$__bstblur"}""{"$__locnorm"}""{"$__filt"}""{"$__dist"}""{"$__distblur"}"\
"{"$__distmerge"}""{"$__diststr"}""{"$__wc"}""{"$__bilsize"}""{"$__bilrep"}""{"$__fuzz"}""{"$__fuzzblur"}""{"$__fuzstr"}""{"$__plsmseed"}""{"$__plsmsat"}""{"$__plasmerge"}"\
"{"$__plastr"}""{"$__cracks"}""{"$__sckrad"}""{"$__sck"}""{"$__lgtone"}""{"$__lgttwo"}""{"$__lgthree"}""{"$__sketch"}""{"$__sklike"}""{"$__cutmin"}""{"$__cutmax"}""{"$__linestr"}"\
"{"$__brkstr"}""{"$__skmerge"}""{"$__noistr"}""{"$cnvs"}""{"$__post"}""{"$__huestr"}""{"$__bri"}""{"$__con"}""{"$__gam"}""{"$__hue"}""{"$__sat"}"

watergmic_previewB :

gui_split_preview "watergmicB $*"