gtutor_tileit — 9153a5c9ec3d: Sat May 29 12:45:28 2021 -0400
#@gui __
#@gui <b>Testing</b>
#@gui <i>Gmic Tutorials</i>
#@gui Rectangular Tiling : _rec_tileit, gtutor_rectangular_tiling_preview
#@gui : documentation = note("Generate a mosaic from an image. Works best with line art cartoons with flat color.")
#@gui : sep = separator()
#@gui : Tile Size = float(1.0,0.05,5.0)
#@gui : Disrupt Orientation = float(5.0,0.0,10.0)
#@gui : Spread Tiles Apart = float(1.5,0.25,5.0)
#@gui : Fill Holes = bool(1)
#@gui : Color Count = int(4,2,32)
#@gui : Flat Color = bool(0)
#@gui : Light Angle = float(45.0,-180,180)
#@gui : Soften Lighting = float(0.5,0.0,5.0)
#@gui : note = note(<small>Author: <i>Garry R. Osgood</i>. Latest Update: <i>2021/29/05</i></small>)
#@gui : url = link("Technical Notes",https://gmic.eu/tutorial/tiled_art.html)
gtutor_rectangular_tiling_preview :
gui_split_preview "gtutor_tileit ${2},${1},${3},${8},${4},${7},${5},${6}",0
is_fc={2*(1-$6)}
u "{$1}{$2}{$3}{$4}{$5}{$6}"\
"{$7}_"$is_fc\
"{$8}_"$is_fc
_rec_tileit:
gtutor_tileit ${2},${1},${3},${8},${4},${7},${5},${6}
#@cli gtutor_tileit : 0<=_disrupt<=10,0.05<_tsize,0.25<=_spread,0<=_soft,_fillholes:True,-180<=_lightangle<=180,2<=_ccount<=32,_fcolor:False
#@cli : Generate a mosaic from an image. Works best with line art cartoons with flat color.
#@cli : disrupt=5 Rotates, scales and displaces tiles. Suggest 0-10.
#@cli : tsize=1.0 Tile size relative to image. 1.0 → tile diagonal is 2.5% of the image diagonal.
#@cli : spread=1.5 Increasing promotes dropped tiles, gaps at junctions and runs. Suggest 0-3.
#@cli : soft=0.5 Soften and dull shadows and highlights. Suggest 0-5.
#@cli : fillholes=1 True: Fill gaps and holes. No alpha channel.
#@cli : False: Leave gaps and holes. Image has alpha channel.
#@cli : lightangle=45° Degrees: -180° – 180°. Lighting angle.
#@cli : 45°: Light appears to stream from viewer's upper left.
#@cli : ccount=4 Set number of dominant colors, taken from those most frequently occuring in source.
#@cli : fcolor=0 True: Flat color tiling without lighting and shading.
#@cli : False: Do tile lighting and shading.
gtutor_tileit : -check "${1=5}>=0 && $1<=10 && ${2=1.0}>=0.05 && ${3=1.5}>=0.25 && ${4=0.5}>=0 && isbool(${5=1}) && ${6=45}>=-180 && ${6}<=180 && ${7=4}>=2 && ${7}<=32 && isbool(${8=0})"
-echo[^-1] "Applying faux tiling to selected images. Disruption: "${1}". Tile size: "${2}". Tile spread: "${3}". Highlight softening: "${4}". Holes: "${arg\ 1+!$5,filling,leaving}". Light angle: "${6}"°. Color count: "${7}", and "${arg\ 1+!$8,unshaded,shaded}" color."
# Parameters
disrupt=$1
tsize=$2*0.025*sqrt(w^2+h^2)
spread=$3
soft=$4
fillholes=$5
lightangle=$6
ccount=$7
fcolor=$8
-repeat $!
-local[$>]
# Color quantization + black
-remove_opacity.
+colormap. ${ccount},1,2
-index.. .,0,1
-round 1
1
-append[-2,-1] x
-name. pallette
-move[pallette] 0
-name. qcolor
+luminance[qcolor]
-name. qlumin
-normalize[qlumin] 0.6,1
# Outline qcolor
-input 100%,100%,1,1,'I(#-2,x,y)==I(#-3,0,0)?1:0'
-fill. ">abs(
i-j(1,1,0,0,0,1)
)>iv?
1:
abs(
i-j(1,0,0,0,0,1)
)>iv?
1:0"
-name[-1] outline
# Cost: perturbs distance to outline measure, a basis of tile irregularity
-input 100%,100%,1,1
-name[-1] cost
-plasma[cost] 4,4,{$disrupt}
-normalize[cost] 0,{$disrupt/4.0}
# Distance to outline + distance perturbation
+distance[outline] 1,[cost],1
-name. distvar
+distance[outline] 1
+add[-1,-2]
-remove[-3,-2]
# True distance: basis for marking off distance by tile height
[-1]
-name[-1] truedistance
# Orient: source of tile rotation
-name[-2] orienter
# Make Warper: distorts tiles
-gradient[cost] xy
-append[-4,-3] c
-blur[-3] 1,1,1
-normalize... {-1.5*$disrupt},{1.5*$disrupt}
-name... warper
# Measure out and scribe tile center-to-center lines
-round[truedistance] {$spread*$tsize}
-fill[truedistance] ">
abs(i-j(1,1,0,0,0,1))>"{0.5*$spread*$tsize}"?
1:
abs(i-j(1,0,0,0,0,1))>"{0.5*$spread*$tsize}"?
1:0
"
# Compute orientation field
-gradient[orienter] xy
-append[-3,-2] c
-orientation[orienter]
# Plotting field:
[-1],[-1],1,4,'[-1,-1,-1,0]'
-name. plottingfield
# Draw tiles on a plotting field:
# (1) xfrm: encodes tile translations and rotations
# for tile corner points. (2) tl, tr, bl, br:
# tile corners, expressed in homogeneous
# coordinates.
-fill[plottingfield] ">if(
0<i#-2 && I#-1==[-1,-1,-1,0],
xfrm=eye(3);
xfrm[0]=I#-3[1];
xfrm[1]=I#-3[0];
xfrm[2]=x;
xfrm[3]=-I#-3[0];
xfrm[4]=I#-3[1];
xfrm[5]=y;
tl=xfrm*[-"$tsize", "$tsize"/2.0,1];
tr=xfrm*[ "$tsize", "$tsize"/2.0,1];
bl=xfrm*[-"$tsize",-"$tsize"/2.0,1];
br=xfrm*[ "$tsize",-"$tsize"/2.0,1];
polygon(#-1,5,
[tl[0],tl[1]],
[tr[0],tr[1]],
[br[0],br[1]],
[bl[0],bl[1]],
[tl[0],tl[1]],
1,[[I#-7]*i#-6,255]);
polygon(#-1,-5,
[tl[0],tl[1]],
[tr[0],tr[1]],
[br[0],br[1]],
[bl[0],bl[1]],
[tl[0],tl[1]],
1,0xffffffff,[0,0,0,255]);
I,I)"
-cut[plottingfield] 0,255
# Make isovalue targets for lighting height map
100%,100%,1,1,'I#-1==[0,0,0,255]?1:0'
-name. heightmap
# Distort artwork
-warp[plottingfield,heightmap] [warper],1,2,2
# Clean up
-remove[-3--6]
-split_opacity[plottingfield]
-index[plottingfield] [pallette],0,1
-remove[pallette]
-fill.. 'i>=127?255:0'
-fill. 'i>0.05?1:0'
-fill. 'i#-2==0?0:i'
-if $fcolor # Do light and shade?
-if $fillholes
# Fill holes in the plotting field
-fill[plottingfield] 'i#-2==0?I#-5*i#-4:I'
-remove[-2]
-else
-append[-3,-2] c
-fi
-keep[plottingfield]
-else
# Distance from edges: proxy for
# tile height. Shape height with
# power function
-distance[heightmap] 1
-normalize[heightmap] 0,1
-pow. 0.25
-blur. 0.875,1,1
-normalize[heightmap] 0,1
-if {$fillholes==0}
# Poke holes in the height map
-fill[heightmap] 'i#-2==0?0:i'
-else
# Fill holes in the plotting field
-fill[plottingfield] 'i#-2==0?I#-5*i#-4:I'
-fi
-remove[qcolor,qlumin]
# Cheap Fingerpaint Lighting
# Derive shadow, hightlight, color
-normalize[plottingfield] 0,1
# Light
+gradient[heightmap] xy
-append[-2,-1] c
({cos($lightangle*pi/180)}^{sin($lightangle*pi/180)})
-resize. [-2],[-2],[-1],[-1],1
+mul[-2,-1]
-compose_channels. add
-name. light
-cut. {ia},{iM}
-normalize. 0,1
-pow. 0.5
if $soft>0
-blur. {$soft},1,1
fi
# Shadow
-mul.. -1
-mul[-3,-2]
-compose_channels.. add
-name.. shadow
-cut.. {ia#-2},{iM#-2}
-normalize.. 0,1
-oneminus..
-pow.. 2
# Composite
-mul[plottingfield,shadow]
-mul[light] '{iM#0}'
-add[plottingfield,light]
-normalize[plottingfield] 0,255
-if {$fillholes==0}
-append[-3,-2] c
-else
-remove..
-fi
-keep[0]
-fi # else doing light and shade
-endlocal
-done