I have been scouring SO and Google search results for almost a week now, trying to make a simple batch script work. I think my problem arises from a lack of understanding Batch FOR loops and DelayedExpansion.
There's a huge amount of related questions and answers on this topic, but not a single one of the posts I have seen is able to break down the information in a way that makes sense to me.
setlocal enabledelayedexpansion
SET /a QUALITY=20
SET /a STEP=5
:loop
convert input.jpg -resize 1080x1080 -quality %quality% -strip ./1080/output.jpg
SET /a quality+=step
for %%G in (./1080/output.jpg) DO (
set filesize=%%~zG
if !filesize! LSS 100000 if !quality! LSS 100 goto loop
)
The intent of this code is to convert (ImageMagick) an image with an initial compression quality of 20, check the filesize, and start over with a slightly higher quality setting each iteration while the filesize is less than 100KB AND the quality is less than 100.
As it is, the output is such:
>SET /a QUALITY=20
>SET /a STEP=5
>convert input.jpg -resize 1080x1080 -quality 20 -strip ./1080/output.jpg
>SET /a quality+=step
>for %G in (./1080/output.jpg) DO (
>set filesize=%~zG
>if !filesize! LSS 100000 if !quality! LSS 100 goto loop
>(
>set filesize=
>if !filesize! LSS 100000 if !quality! LSS 100 goto loop
>)
>convert export.jpg -resize 1080x1080 -quality 25 -strip ./1080/output.jpg
... etc (infinite loop). This loops until killed.
The output.jpg in this particular test run (quality at 20) has a filesize of 82.3KB, which is less than the 100KB threshold and should therefore 'goto loop' and generate an output.jpg (quality at 25) with a filesize of 96.4KB, 'goto loop', and generate a final output.jpg (quality at 30) with a filesize of 109KB.
I believe that the desired output should be something like this:
>SET /a QUALITY=20
>SET /a STEP=5
>convert input.jpg -resize 1080x1080 -quality 20 -strip ./1080/output.jpg
>SET /a quality+=step
>SET filesize=82300
>if 82300 LSS 100000 if 20 LSS 100 goto loop
>convert input.jpg -resize 1080x1080 -quality 25 -strip ./1080/output.jpg
>SET /a quality+=step
>SET filesize=96400
>if 96400 LSS 100000 if 25 LSS 100 goto loop
>convert input.jpg -resize 1080x1080 -quality 30 strip ./1080/output.jpb
>SET /a quality+=step
>SET filesize=109000
>if 109000 LSS 100000 if 30 LSS 100 goto loop
>
EDIT: I've tried implementing suggestions from David Ruhmann and Mike Nakis, and also an OR trick from this post here. Unfortunately, the resulting code seems to have the same problem as before, and I am left with an infinite loop (incrementing in quality each time).
SET /a QUALITY=30
SET /a STEP=5
md large
:loop
convert export.jpg -resize 1080x1080 -quality %quality% -strip ./large/xhdpi.jpg
@set res=true
@echo Quality = %quality%
@SET /a quality+=step
@for %%G in (./large/xhdpi*) DO (if %%~zG GTR 100000 set res=false)
@for %%G in (./large/xhdpi*) DO (if !quality! GTR 100 set res=false)
@if "%res%"=="false" exit /b
@if "%res%"=="true" goto loop
It would seem that the true issue at fault in my code is that %%~zG is not being assigned a value. Why is %%G returning an empty string?