ic

来自Tsetien’s Wiki
跳转到导航 跳转到搜索

A tiny little Windows Batch script used for the cropping, scaling, and format conversion of images. It requires the following software to be properly set up in %PATH% (here in my case is C:\_c\):

Understanding ‘orientation-adaptive’ and ‘orientation-irrelevant’

As the script is used for the cropping and scaling of images, it would require the clarification of two concepts: ‘orientation-adaptive’ and ‘orientation-irrelevant’.

The former, as its name indicates, takes the image’s orientation into account. This can be easily understood in the context of scaling, as we often do need to scale an image by its ‘long edge’ or ‘short edge’, regardless of whether it is the width or the height.

It might get a little bit confusing when it comes to cropping. In cropping, by saying ‘orientation-adaptive’, it means that when given a ratio, the long edge always takes the first number, while the short edge takes the second. For example, if we have a horizontal image (which means its width is greater than its height), and we want to crop it to 4:3 orientation-adaptively, then the long edge, the width, will take the ‘4’ while the short edge, the height, will take the ‘3’. And when done, it would indeed be an image of 4:3. But if we have a vertical image (which means the height is the longer edge), and we still want to orientation-adaptively crop it to 4:3, then the height of the image, now the long edge, shall take the ‘4’, while the width of the image will take the ‘3’, and the final result we get is actually an image of 3:4.

What makes the ‘orientation-adaptive cropping’ more confusing is that it can be used to crop ‘against’ the image’s orientation by setting a ratio smaller than 1, in that it can force the long edge to take the smaller number in the ratio to become the new short edge while the original short edge can take the larger number and becomes the new long edge.

The ‘orientation-irrelevant’ scaling or cropping is much easier to understand—as its name indicates, it does not take the image’s orientation into account, only focusing on scaling or cropping based on the width and height, regardless of which one is longer.

Cropping switches

The script accepts switches used for cropping in an order of precedence as follows—if more than one switch is detected in one operation, a switch with a higher rank surpasses the lower ones:

  • -sq: crops the image to a 1:1 square;
  • -gr: orientation-adaptively crops the image to the golden ratio;
  • -gx: orientation-irrelevantly crops the image to the golden ratio by setting its width as the long edge;
  • -gy: orientation-irrelevantly crops the image to the golden ratio by setting its height as the long edge;
  • -cr x y: orientation-adaptively crops the image to a set ratio of x:y, where the long edge of the image takes the x, and the short edge takes the y;
  • -cx x y: orientation-irrelevantly crops the image to a set ratio of x:y, where the width of the image takes the x, and the height takes the y; and
  • -rg: performs a ‘reversed’ orientation-adaptive golden ratio cropping, where the long edge of the image takes the smaller number of the golden ratio, and the short edge takes the larger (not very useful actually, and that’s why it gets the lowest precedence).

Scaling switches

The script accepts switches used for scaling in an order of precedence as follows—if more than one switch is detected in one operation, a switch with a higher rank surpasses the lower ones:

  • -sl x: proportionally scales the image by setting its long edge to x;
  • -ss x: proportionally scales the image by setting its short edge to x;
  • -sx x: proportionally scales the image by setting its width to x;
  • -sy x: proportionally scales the image by setting its height to x;
  • -sf x y: proportionally scales the image by a given fraction of x/y; and
  • -sp x: proportionally scales the image by a given percentage x (‘%’ is not needed when giving the percentage number).

The script, by default, prohibits upscaling, unless the user explicitly orders the script to do so by changing the first letter of these scaling switches to ‘u’ (-ul, -us, -ux, etc). I strongly dissuade anyone who intends to use this script to upscale any image, for that image upscaling simply shall not be done in this way as it needs much more complicated algorithms and should be done with dedicated manual tuning.

Output file format and quality switches

The script accepts switches -p, -j, and -w to indicate an output of a .png image, a .jpg image, or a .webp image. These switches can be used simultaneously to output more than one image. For -j and -w, there are four quality suffixes, hq (‘highest quality’), mq (‘medium quality’), lq (‘low quality’), and pq (‘poor quality’), each representing a fixed quality parameter (or a group of fixed quality-related parameters in the case of -w), that can be used by immediately appending to the letter j or q, with no spaces in between, to form a five-tier image quality levels (together with the two default ones of no sticking letters, the -j and -w, which are both ranked second best in the hierarchy) for the user to choose. And by knowing me, you can rest assured that even by using -jpq or -wpq, the output will still be acceptable. But if a specific quality number is particularly desired, the user can indeed use -jq n or -wq n to pass that specific quality number to the script. If -p is detected, then the output .png file will be compressed by optipng with maximum tries, which means it will take a considerably long period of time if the image is large. Lastly, all of the output files will be cleaned of EXIF information in the end and no option is provided to prevent this operation—that is the design.

Designating output filename and path

By default, the output file or files will be saved in the same location as the input file, using the original filename as the basename with text labels of the process or processes being done to it and of the image quality parameter appended in the end. And yet the output filename and path are designatable with the switches listed below:

  • -op "path\to\the\designated location\": if used, the output files will then be exported to the designated location;
  • -ob new_basename: if used, then the given string will surpass the file’s original name and be used as the designated basename—the text labels for processed and image quality will still be appended to the given basename; and
  • -on "new filename": if used, then the given string will be used as the full filename of the output file, with no more appendings.

Since one operation of the script can produce more than one file in different formats, strings given after -ob and -on shall not contain a file extension, as it will be added automatically according to the output format.

If -k is detected, then the intermediary .png file used during the process will be kept and will not be compressed (meaning it will be large, considerably large), with an ‘-interim’ label attached to the end of the filename.

The batch

ic.bat
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
set "a="
set "i="
set "k="
set "fn="
set "bn="
set "on="
set "gn="
set "np="
set "op="
set "cm="
set "sm="
set "hg="
set "jq="
set "wq="
set "sl="
set "sp="
set "ss="
set "sx="
set "sy="
set "cr1="
set "cr2="
set "cx1="
set "cx2="
set "sf1="
set "sf2="
set "cmb="
set "smb="
set "vfb="
set "cpf="
set "spf="
set "jpg="
set "png="
set "wbp="
set "sns="
:a
if /i "%~1"=="" goto p
set "a=%~1"
if /i "!a:~0,1!"=="-" (
	if /i "!a!"=="-op" (set "np=%~2" & shift)
	if /i "!a!"=="-on" (set "gn=%~2" & set "hg=1" & shift)
	if /i "!a!"=="-ob" (set "bn=%~2" & shift)
	if /i "!a!"=="-p" (set "png=1")
	if /i "!a!"=="-k" (set "k=1")
	if /i "!a!"=="-wpq" (set "wbp=1" & set "sns=80" & set "wq=80")
	if /i "!a!"=="-wlq" (set "wbp=1" & set "sns=50" & set "wq=85")
	if /i "!a!"=="-wmq" (set "wbp=1" & set "sns=20" & set "wq=90")
	if /i "!a!"=="-w" (set "wbp=1" & set "sns=0" & set "wq=95")
	if /i "!a!"=="-whq" (set "wbp=1" & set "sns=0" & set "wq=99")
	if /i "!a!"=="-wq" (set "wbp=1" & set "sns=0" & set "wq=%~2" & shift)
	if /i "!a!"=="-jpq" (set "jpg=1" & set "jq=80")
	if /i "!a!"=="-jlq" (set "jpg=1" & set "jq=85")
	if /i "!a!"=="-jmq" (set "jpg=1" & set "jq=90")
	if /i "!a!"=="-j" (set "jpg=1" & set "jq=95")
	if /i "!a!"=="-jhq" (set "jpg=1" & set "jq=99")
	if /i "!a!"=="-jq" (set "jpg=1" & set "jq=%~2" & shift)
	if /i "!a!"=="-rg" (set "cm=rg" & set "cpf=rgr")
	if /i "!a!"=="-cx" (set "cm=cx" & set "cx1=%~2" & set "cx2=%~3" & set "cpf=wth!cx1!t!cx2!" & shift & shift)
	if /i "!a!"=="-cr" (set "cm=cr" & set "cr1=%~2" & set "cr2=%~3" & set "cpf=lts!cr1!t!cr2!" & shift & shift)
	if /i "!a!"=="-gy" (set "cm=gy" & set "cpf=grv")
	if /i "!a!"=="-gx" (set "cm=gx" & set "cpf=grh")
	if /i "!a!"=="-gr" (set "cm=gr" & set "cpf=gr")
	if /i "!a!"=="-sq" (set "cm=sq" & set "cpf=sq")
	if /i "!a!"=="-up" (set "sm=up" & set "sp=%~2" & set "spf=!sp!pc" & shift)
	if /i "!a!"=="-uf" (set "sm=uf" & set "sf1=%~2" & set "sf2=%~3" & set "spf=!sf1!d!sf2!" & shift & shift)
	if /i "!a!"=="-uy" (set "sm=uy" & set "sy=%~2" & set "spf=x!sy!" & shift)
	if /i "!a!"=="-ux" (set "sm=ux" & set "sx=%~2" & set "spf=!sx!x" & shift)
	if /i "!a!"=="-us" (set "sm=us" & set "ss=%~2" & set "spf=s!ss!" & shift)
	if /i "!a!"=="-ul" (set "sm=ul" & set "sl=%~2" & set "spf=l!sl!" & shift)
	if /i "!a!"=="-sp" (set "sm=sp" & set "sp=%~2" & set "spf=!sp!pc" & shift)
	if /i "!a!"=="-sf" (set "sm=sf" & set "sf1=%~2" & set "sf2=%~3" & set "spf=!sf1!d!sf2!" & shift & shift)
	if /i "!a!"=="-sy" (set "sm=sy" & set "sy=%~2" & set "spf=x!sy!" & shift)
	if /i "!a!"=="-sx" (set "sm=sx" & set "sx=%~2" & set "spf=!sx!x" & shift)
	if /i "!a!"=="-ss" (set "sm=ss" & set "ss=%~2" & set "spf=s!ss!" & shift)
	if /i "!a!"=="-sl" (set "sm=sl" & set "sl=%~2" & set "spf=l!sl!" & shift)
) else (
	if not defined i set "i=%~1"
	for %%f in ("!i!") do set "op=%%~dpf" & set "on=%%~nf"
)
shift
goto a
:p
if /i "!np!"=="" set "np=!op!"
if /i not "!np:~-1!"=="\" set "np=!np!\"
if not exist "!np!" md "!np!"
if /i "!bn!"=="" set "bn=!on!"
if defined cpf set "cpf=-!cpf!"
if defined spf set "spf=-!spf!"
if /i "!gn!"=="" set "gn=!bn!!cpf!!spf!"
if defined cm (
	if /i "!cm!"=="cx" set "cmb=crop='floor(if(gte(iw/ih,!cx1!/!cx2!),ih*!cx1!/!cx2!,iw)/2)*2:floor(if(gte(iw/ih,!cx1!/!cx2!),ih,iw*!cx2!/!cx1!)/2)*2'"
	if /i "!cm!"=="cr" set "cmb=crop='floor(if(gte(iw,ih),min(iw,ih*(!cr1!/!cr2!)),min(iw,ih*(!cr2!/!cr1!)))/2)*2:floor(if(gte(iw,ih),min(ih,iw*(!cr2!/!cr1!)),min(ih,iw*(!cr1!/!cr2!)))/2)*2'"
	if /i "!cm!"=="rg" set "cmb=crop='floor(if(gte(iw,ih),min(iw,ih*(17711/28657)),min(iw,ih*(28657/17711)))/2)*2:floor(if(gte(iw,ih),min(ih,iw*(28657/17711)),min(ih,iw*(17711/28657)))/2)*2'"
	if /i "!cm!"=="gy" set "cmb=crop='floor(if(gte(iw/ih,17711/28657),ih*17711/28657,iw)/2)*2:floor(if(gte(iw/ih,17711/28657),ih,iw*28657/17711)/2)*2'"
	if /i "!cm!"=="gx" set "cmb=crop='floor(if(gte(iw/ih,28657/17711),ih*28657/17711,iw)/2)*2:floor(if(gte(iw/ih,28657/17711),ih,iw*17711/28657)/2)*2'"
	if /i "!cm!"=="gr" set "cmb=crop='floor(if(gte(iw,ih),min(iw,ih*(28657/17711)),min(iw,ih*(17711/28657)))/2)*2:floor(if(gte(iw,ih),min(ih,iw*(17711/28657)),min(ih,iw*(28657/17711)))/2)*2'"
	if /i "!cm!"=="sq" set "cmb=crop='floor(min(iw,ih)/2)*2:floor(min(iw,ih)/2)*2'"
)
if defined sm (
	if /i "!sm!"=="sp" set "smb=scale='if(lte(!sp!,100),floor(iw*!sp!/100),iw):if(lte(!sp!,100),floor(ih*!sp!/100),ih):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
	if /i "!sm!"=="sf" set "smb=scale='if(lte(iw*!sf1!/!sf2!,iw),floor(iw*!sf1!/!sf2!),iw):if(lte(ih*!sf1!/!sf2!,ih),floor(ih*!sf1!/!sf2!),ih):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
	if /i "!sm!"=="sy" set "smb=scale='-2:if(lte(!sy!,ih),!sy!,ih):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
	if /i "!sm!"=="sx" set "smb=scale='if(lte(!sx!,iw),!sx!,iw):-2:flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
	if /i "!sm!"=="ss" set "smb=scale='if(lt(iw,ih),min(!ss!,iw),-2):if(gte(iw,ih),min(!ss!,ih),-2):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
	if /i "!sm!"=="sl" set "smb=scale='if(gte(iw,ih),min(!sl!,iw),-2):if(lt(iw,ih),min(!sl!,ih),-2):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
	if /i "!sm!"=="up" set "smb=scale='floor(iw*!sp!/100):floor(ih*!sp!/100):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
	if /i "!sm!"=="uf" set "smb=scale='floor(iw*!sf1!/!sf2!):floor(ih*!sf1!/!sf2!):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
	if /i "!sm!"=="uy" set "smb=scale=-2:!sy!:flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4"
	if /i "!sm!"=="ux" set "smb=scale=!sx!:-2:flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4"
	if /i "!sm!"=="us" set "smb=scale='if(lt(iw,ih),!ss!,-2):if(gte(iw,ih),!ss!,-2):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
	if /i "!sm!"=="ul" set "smb=scale='if(gte(iw,ih),!sl!,-2):if(lt(iw,ih),!sl!,-2):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'"
)
if defined cm if not defined sm (set "vfb=!cmb!")
if not defined cm if defined sm (set "vfb=format=rgba64le,!smb!,format=rgba64le,setsar=1")
if defined cm if defined sm (set "vfb=format=rgba64le,!cmb!,!smb!,format=rgba64le,setsar=1")
if not defined vfb (
	ffmpeg -i "!i!" -vframes:v 1 -update true -compression_level 0 "!op!!on!_intermediateagzk3kXe8nDr.png" -y
) else (
	ffmpeg -i "!i!" -vframes:v 1 -update true -compression_level 0 -vf "!vfb!" "!op!!on!_intermediateagzk3kXe8nDr.png" -y
)
if /i "!jpg!"=="1" (
	cjpegli -q !jq! --chroma_subsampling=444 "!op!!on!_intermediateagzk3kXe8nDr.png" "!op!!on!_intermediateagzk3kXe8nDr.jpg"
	exiftool -overwrite_original -all= "!op!!on!_intermediateagzk3kXe8nDr.jpg"
	if /i "!hg!"=="1" (
		move /y "!op!!on!_intermediateagzk3kXe8nDr.jpg" "!np!!gn!.jpg"
	) else (
		move /y "!op!!on!_intermediateagzk3kXe8nDr.jpg" "!np!!gn!-q!jq!.jpg"
	)
)
if /i "!wbp!"=="1" (
	cwebp -mt -q !wq! -m 6 -sharp_yuv -af -alpha_filter best -sns !sns! "!op!!on!_intermediateagzk3kXe8nDr.png" -o "!op!!on!_intermediateagzk3kXe8nDr.webp"
	exiftool -overwrite_original -all= "!op!!on!_intermediateagzk3kXe8nDr.webp"
	if /i "!hg!"=="1" (
		move /y "!op!!on!_intermediateagzk3kXe8nDr.webp" "!np!!gn!.webp"
	) else (
		move /y "!op!!on!_intermediateagzk3kXe8nDr.webp" "!np!!gn!-q!wq!.webp"
	)
)
if /i "!png!"=="1" (
	ffmpeg -i "!op!!on!_intermediateagzk3kXe8nDr.png" -vframes:v 1 -update true -compression_level 0 -pix_fmt rgba "!op!!on!_intermediateagzk3kXe8nDr1.png" -y
	optipng -o7 -zm1-9 "!op!!on!_intermediateagzk3kXe8nDr1.png"
	exiftool -overwrite_original -all= "!op!!on!_intermediateagzk3kXe8nDr1.png"
	move /y "!op!!on!_intermediateagzk3kXe8nDr1.png" "!np!!gn!.png"
)
if /i "!k!"=="1" (
	exiftool -overwrite_original -all= "!op!!on!_intermediateagzk3kXe8nDr.png"
	move /y "!op!!on!_intermediateagzk3kXe8nDr.png" "!np!!gn!-interim.png"
) else (
	del /q "!op!!on!_intermediateagzk3kXe8nDr.png"
)
endlocal

And the bash translation

Translated by ChatGPT 5.1, not tested, should be fine, though.

ic
#!/bin/bash
set -euo pipefail
i=
op=
on=
bn=
gn=
np=
k=
jpg=
png=
wbp=
jq=
wq=
sns=
cm=
sm=
cx1=
cx2=
cr1=
cr2=
sf1=
sf2=
sx=
sy=
ss=
sl=
sp=
cpf=
spf=
hg=
while [ "$#" -gt 0 ]; do
	a="$1"
	case "$a" in
		-op) np="$2"; shift;;
		-on) gn="$2"; hg=1; shift;;
		-ob) bn="$2"; shift;;
		-p) png=1;;
		-k) k=1;;
		-wpq) wbp=1; sns=80; wq=80;;
		-wlq) wbp=1; sns=50; wq=85;;
		-wmq) wbp=1; sns=20; wq=90;;
		-w) wbp=1; sns=0; wq=95;;
		-whq) wbp=1; sns=0; wq=99;;
		-wq) wbp=1; sns=0; wq="$2"; shift;;
		-jpq) jpg=1; jq=80;;
		-jlq) jpg=1; jq=85;;
		-jmq) jpg=1; jq=90;;
		-j) jpg=1; jq=95;;
		-jhq) jpg=1; jq=99;;
		-jq) jpg=1; jq="$2"; shift;;
		-rg) cm=rg; cpf=rgr;;
		-cx) cm=cx; cx1="$2"; cx2="$3"; cpf="wth${cx1}t${cx2}"; shift; shift;;
		-cr) cm=cr; cr1="$2"; cr2="$3"; cpf="lts${cr1}t${cr2}"; shift; shift;;
		-gy) cm=gy; cpf=grv;;
		-gx) cm=gx; cpf=grh;;
		-gr) cm=gr; cpf=gr;;
		-sq) cm=sq; cpf=sq;;
		-up) sm=up; sp="$2"; spf="${sp}pc"; shift;;
		-uf) sm=uf; sf1="$2"; sf2="$3"; spf="${sf1}d${sf2}"; shift; shift;;
		-uy) sm=uy; sy="$2"; spf="x${sy}"; shift;;
		-ux) sm=ux; sx="$2"; spf="${sx}x"; shift;;
		-us) sm=us; ss="$2"; spf="s${ss}"; shift;;
		-ul) sm=ul; sl="$2"; spf="l${sl}"; shift;;
		-sp) sm=sp; sp="$2"; spf="${sp}pc"; shift;;
		-sf) sm=sf; sf1="$2"; sf2="$3"; spf="${sf1}d${sf2}"; shift; shift;;
		-sy) sm=sy; sy="$2"; spf="x${sy}"; shift;;
		-sx) sm=sx; sx="$2"; spf="${sx}x"; shift;;
		-ss) sm=ss; ss="$2"; spf="s${ss}"; shift;;
		-sl) sm=sl; sl="$2"; spf="l${sl}"; shift;;
		-*)
			:
		;;
		*)
			if [ -z "$i" ]; then
				i="$a"
				op="$(dirname "$i")/"
				on="$(basename "$i")"
				on="${on%.*}"
			fi
		;;
	esac
	shift
done
[ -z "$np" ] && np="$op"
case "$np" in */);; *) np="${np}/";; esac
mkdir -p "$np"
[ -z "$bn" ] && bn="$on"
[ -n "$cpf" ] && cpf="-${cpf}"
[ -n "$spf" ] && spf="-${spf}"
[ -z "$gn" ] && gn="${bn}${cpf}${spf}"
if [ -n "$cm" ]; then
	case "$cm" in
		cx) cmb="crop='floor(if(gte(iw/ih,${cx1}/${cx2}),ih*${cx1}/${cx2},iw)/2)*2:floor(if(gte(iw/ih,${cx1}/${cx2}),ih,iw*${cx2}/${cx1})/2)*2'";;
		cr) cmb="crop='floor(if(gte(iw,ih),min(iw,ih*(${cr1}/${cr2})),min(iw,ih*(${cr2}/${cr1})))/2)*2:floor(if(gte(iw,ih),min(ih,iw*(${cr2}/${cr1})),min(ih,iw*(${cr1}/${cr2})))/2)*2'";;
		rg) cmb="crop='floor(if(gte(iw,ih),min(iw,ih*(17711/28657)),min(iw,ih*(28657/17711)))/2)*2:floor(if(gte(iw,ih),min(ih,iw*(28657/17711)),min(ih,iw*(17711/28657)))/2)*2'";;
		gy) cmb="crop='floor(if(gte(iw/ih,17711/28657),ih*17711/28657,iw)/2)*2:floor(if(gte(iw/ih,17711/28657),ih,iw*28657/17711)/2)*2'";;
		gx) cmb="crop='floor(if(gte(iw/ih,28657/17711),ih*28657/17711,iw)/2)*2:floor(if(gte(iw/ih,28657/17711),ih,iw*17711/28657)/2)*2'";;
		gr) cmb="crop='floor(if(gte(iw,ih),min(iw,ih*(28657/17711)),min(iw,ih*(17711/28657)))/2)*2:floor(if(gte(iw,ih),min(ih,iw*(17711/28657)),min(ih,iw*(28657/17711)))/2)*2'";;
		sq) cmb="crop='floor(min(iw,ih)/2)*2:floor(min(iw,ih)/2)*2'";;
	esac
fi
if [ -n "$sm" ]; then
	case "$sm" in
		sp) smb="scale='if(lte(${sp},100),floor(iw*${sp}/100),iw):if(lte(${sp},100),floor(ih*${sp}/100),ih):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
		sf) smb="scale='if(lte(iw*${sf1}/${sf2},iw),floor(iw*${sf1}/${sf2}),iw):if(lte(ih*${sf1}/${sf2},ih),floor(ih*${sf1}/${sf2}),ih):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
		sy) smb="scale='-2:if(lte(${sy},ih),${sy},ih):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
		sx) smb="scale='if(lte(${sx},iw),${sx},iw):-2:flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
		ss) smb="scale='if(lt(iw,ih),min(${ss},iw),-2):if(gte(iw,ih),min(${ss},ih),-2):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
		sl) smb="scale='if(gte(iw,ih),min(${sl},iw),-2):if(lt(iw,ih),min(${sl},ih),-2):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
		up) smb="scale='floor(iw*${sp}/100):floor(ih*${sp}/100):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
		uf) smb="scale='floor(iw*${sf1}/${sf2}):floor(ih*${sf1}/${sf2}):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
		uy) smb="scale=-2:${sy}:flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4";;
		ux) smb="scale=${sx}:-2:flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4";;
		us) smb="scale='if(lt(iw,ih),${ss},-2):if(gte(iw,ih),${ss},-2):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
		ul) smb="scale='if(gte(iw,ih),${sl},-2):if(lt(iw,ih),${sl},-2):flags=lanczos+accurate_rnd+full_chroma_inp+full_chroma_int:param0=4'";;
	esac
fi
if [ -n "$cm" ] && [ -z "$sm" ]; then
	vfb="$cmb"
elif [ -z "$cm" ] && [ -n "$sm" ]; then
	vfb="format=rgba64le,${smb},format=rgba64le,setsar=1"
elif [ -n "$cm" ] && [ -n "$sm" ]; then
	vfb="format=rgba64le,${cmb},${smb},format=rgba64le,setsar=1"
fi
if [ -z "$vfb" ]; then
	ffmpeg -i "$i" -vframes 1 -update true -compression_level 0 "${op}${on}_intermediateagzk3kXe8nDr.png" -y
else
	ffmpeg -i "$i" -vframes 1 -update true -compression_level 0 -vf "$vfb" "${op}${on}_intermediateagzk3kXe8nDr.png" -y
fi
if [ "$jpg" = 1 ]; then
	cjpegli -q "$jq" --chroma_subsampling=444 "${op}${on}_intermediateagzk3kXe8nDr.png" "${op}${on}_intermediateagzk3kXe8nDr.jpg"
	exiftool -overwrite_original -all= "${op}${on}_intermediateagzk3kXe8nDr.jpg"
	if [ "$hg" = 1 ]; then
		mv -f "${op}${on}_intermediateagzk3kXe8nDr.jpg" "${np}${gn}.jpg"
	else
		mv -f "${op}${on}_intermediateagzk3kXe8nDr.jpg" "${np}${gn}-q${jq}.jpg"
	fi
fi
if [ "$wbp" = 1 ]; then
	cwebp -mt -q "$wq" -m 6 -sharp_yuv -af -alpha_filter best -sns "$sns" "${op}${on}_intermediateagzk3kXe8nDr.png" -o "${op}${on}_intermediateagzk3kXe8nDr.webp"
	exiftool -overwrite_original -all= "${op}${on}_intermediateagzk3kXe8nDr.webp"
	if [ "$hg" = 1 ]; then
		mv -f "${op}${on}_intermediateagzk3kXe8nDr.webp" "${np}${gn}.webp"
	else
		mv -f "${op}${on}_intermediateagzk3kXe8nDr.webp" "${np}${gn}-q${wq}.webp"
	fi
fi
if [ "$png" = 1 ]; then
	ffmpeg -i "${op}${on}_intermediateagzk3kXe8nDr.png" -vframes 1 -update true -compression_level 0 -pix_fmt rgba "${op}${on}_intermediateagzk3kXe8nDr1.png" -y
	optipng -o7 -zm1-9 "${op}${on}_intermediateagzk3kXe8nDr1.png"
	exiftool -overwrite_original -all= "${op}${on}_intermediateagzk3kXe8nDr1.png"
	mv -f "${op}${on}_intermediateagzk3kXe8nDr1.png" "${np}${gn}.png"
fi
if [ "$k" = 1 ]; then
	exiftool -overwrite_original -all= "${op}${on}_intermediateagzk3kXe8nDr.png"
	mv -f "${op}${on}_intermediateagzk3kXe8nDr.png" "${np}${gn}-interim.png"
else
	rm -f "${op}${on}_intermediateagzk3kXe8nDr.png"
fi