A simple, but new filter which shears image is coming

So, I’m not making much filters as I used to as I’m reworking on old ones. But, I think this counts as new, or just reworked rep_skew.

During the road trip, a light bulb moment came when I wanted to implement a few things missing in rep_skew filter, but decided to recode from scratch and made a new rep_shear which will replace it. I didn’t have my other G’MIC code as it is in my desktop, and I had my laptop, so I made this to speed up the time.

I’ll make the GUI version soon and push it to gmic-community.

Just 85 lines of code.

#@cli rep_shear: combined_axis={ 0,xy | 1,xz | 2,xc | 3,yx | 4,yz | 5,yc | 6,zx | 7,zy | 8,zc | 9,cx | 10,cy | 11,cz },angle,centre,_boundary={ 0=none | 1=neumann | 2=periodic | 3=mirror },_interpolation={ 0=nearest | 1=linear | 2=bicubic },_output_mode={ 0=cropped | 1=full }
#@cli : Shear Image Based on angle.
#@cli : Default values: '_boundary=2','_interpolation=2','_output_mode=0'
rep_shear:
skip ${4=2},${5=2},${6=0}

check inrange($2,-90,90,0,0)&&isfinite($3)&&isint($4,0,3)&&isint($5,0,2)&&isbool($6)
if !$2 return fi

x,y,z,c,centre=0,1,2,3,{ispercentage($3)?$3:($3+1)/2}

check inrange($centre,0,1,1,1)

if isnum($1)
	check isint($1,0,11)
	loc=${arg\ $1+1,xy,xz,xc,yx,yz,yc,zx,zy,zc,cx,cy,cz}
else
	loc={'xyzc'}
	check v='$1';size(v)==2?(isin(v[0],$loc)&&isin(v[1],$loc)&&v[0]!=v[1]);
	loc=$1
fi

d,l={`v='$loc';[v[0],_',',v[1]]`} # distance/distancia & line/linea

t_length,t_mult=${arg0\ ${$l},w,h,d,s},{tan($2°)}
ref_length,shift_scale=$t_length-1,$t_mult*half_ref_length
c_interpolation_mode={${$d}==3}

# Workaround as G'MIC JIT compiler doesn't support interpolation within non-spatial dimension c
if $c_interpolation_mode&&$5
	p_arg,s_arg=${arg0\ ${$l},xczy,cyzx,xycz},${arg0\ ${$l},yx,xy,zc}
	permute $p_arg
	rep_shear $s_arg,${2-6}
	permute $p_arg
	return
fi

contain_c={same(_'$d',_'c')||same(_'$l',_'c')}

c0,c1,c2,c3=0
d0,d1,d2,d3=w,h,d,s

if $6
	ins_l=#-1,
	t_dim=${arg0\ ${$d},w,h,d,s}
	df=ceil($t_dim+(abs($t_mult)*$t_length))
	c${$d}=($l-half_ref_length)/half_ref_length*shift_scale-offset
else
	c${$d}=($l-centre)/half_ref_length*shift_scale
fi

if $contain_c
	skew_expr=j($ins_l$c0,$c1,$c2,$c3,$5,$4)
else
	skew_expr=J($ins_l$c0,$c1,$c2,$5,$4)
fi

if $6
	foreach {
		dist={$df}
		d${$d}=$dist
		offset={($dist-$t_dim)/2}

		if prod($d0,$d1,$d2,$d3)/$_cpus>0x400000 error exc_dim_lim fi

		{[$d0,$d1,$d2,$d3]},"begin(
				const ref_length=max(1,"$ref_length");
				const half_ref_length=ref_length/2;
				const offset=$offset;
				const shift_scale="$shift_scale";
			);
			"$skew_expr";
			"

		rm..
	}
else
	fill "begin(
			const ref_length="$ref_length";
			const half_ref_length=ref_length/2;
			const centre=ref_length*$centre;
			const shift_scale="$shift_scale";
		);
		"$skew_expr";"
fi

- Some picture examples -

Shear color channels perpendicular to x/y axis respectively

Left shears within x-axis perpendicular to y axis, and the right is the inverse.

And that’s not all, you can also have a non-cropped version:

Even z axis can be sheared. So, you can shear along z perpendicular to a different axis too!

1 Like

It is now here by the way.

1 Like

Nice that you continue to develop things.