0

I am trying to use a batch script and a for loop command to find all jpg files in the working directory and then use a second for command loop to extract the image dimensions 'wxh' value for each jpg image found and temporarily store the result in a variable fsize to be used later in the script... when running imagemagick command line.

I will then run ImageMagick to optimize all the jpg files using the following command line that requires the wxh that was stored previously in the fsize variable. Since there may be multiple jpg files to act on I need to loop the command one at a time until the last image is processed by imagemagick.

I am having trouble figuring out how to keep the loop going.

I am able to get each jpg file size wxh and store it in the fsize var but when all the images have finished running the image dimensions for the jpg files don't match the original files..... this must have an error in the script and I am struggling to find the issue.

This is where I am stuck.... does anyone see something I have missed?

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

FOR /R %%G IN (*.jpg) DO (
    SET fpath=%%~fG
    SET fname=%%~nG
FOR /F "TOKENS=3" %%I IN ('MAGICK identify "!fpath!"') DO (
    SET fsize=%%I

IF "!fname!.jpg"=="!fname:*.png=!" (
    CALL :RunMagick fpath fname fsize

GOTO END

:RunMagick
ECHO MOGRIFY -monitor -path "output/!fname!" -filter Triangle -define filter:support=2 -thumbnail !fsize! -unsharp 0.25x0.08+8.3+0.045 -dither None -posterize 136 -quality 82 -define jpeg:fancy-upsampling=off -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -define png:exclude-chunk=all -interlace none -colorspace sRGB -format jpg "!fname!"
    )
)
EXIT /B

    IF "%ERRORLEVEL%"=="0" GOTO :END
        ECHO.
        ECHO ERROR LINE 12: && ECHO.
        ECHO CHECK SCRIPT FOR ERRORS
        PAUSE >NUL
        EXIT

:END
ECHO.
ECHO END OF SCRIPT REACHED.
PAUSE>NUL
EXIT
slyfox1186
  • 301
  • 1
  • 13
  • What are you actually trying to do, please? And why do you have all those PNG-only parameters in your command if you are only reading and writing JPEGs? – Mark Setchell Sep 24 '20 at 15:35
  • The command line I am dead set on using with imagemagick takes the jpg files and shrinks the total file size, and improves the image quality to my satisfaction. Part of the command line I DO NOT want to change with imagemagick requires you input the jpg widthxheight for EACH input image being processed. I need to batch process these images fast. So I need to know each images dimensions to satisfy the Imagemagick CLI command which like i said REQUIRES the wxh of each jpg image to execute corectly. I want the original wxh to be identical to output file. – slyfox1186 Sep 24 '20 at 15:39
  • Why not use v7 **ImageMagick** which will allow you to get the geometry and use it all in one go? – Mark Setchell Sep 24 '20 at 15:41
  • What can I say, for all the user manual searching i never have come across what you are recommending i do to make this a peice of cake. I have no idea what you mean and I will try my best to find information that will help me understand what you just recommeneded. I would be grateful if you would give me a gentle push in the right direction.... I can run with it from there if I can just find a place that explains whatever you are talking about.... thanks for the heads up.... – slyfox1186 Sep 24 '20 at 15:45
  • 1
    You've got a label (`:RunMagick`) inside a parenthesised block of code, which can't be done; as soon as you jump there (`goto`, `call`) you're going to break the block context… – aschipfl Sep 24 '20 at 15:50
  • Thank you for catching that. I am going to try and remove the :RunMagick label from the inside of the code block as you pointed out...... thank you for catching that.... – slyfox1186 Sep 24 '20 at 15:52
  • 1
    Look at `%G` on this page if you want the geometry (WxH) of the image https://imagemagick.org/script/escape.php – Mark Setchell Sep 24 '20 at 15:52
  • very interesting page mark, i hope it pans out more easily than the way I am approcahing it even thought I KNOW my method should be easy... i am just butchering the code and I need to get myself out of it... thanks for the extra advice... this is why I come here to ask for help from you guys. – slyfox1186 Sep 24 '20 at 15:56
  • Have a look at @GeeMack answers too as he uses them (and Windows a lot) https://stackoverflow.com/search?q=user%3A8174768+%5Bimagemagick%5D – Mark Setchell Sep 24 '20 at 16:12
  • You could also consider processing images in parallel if you are in a hurry and have a decent CPU. – Mark Setchell Sep 24 '20 at 19:20
  • Mark I have an extremely powerful PC. what are you getting at when you mentioned processing images in parallel. I'm struggling to follow you’re thought process. – slyfox1186 Sep 24 '20 at 20:28
  • I don't know what you are trying to do, but if you have lots of images to process and want them done sooner, you could probably do them in parallel. If you have 4 CPU cores you could maybe generate a list of all your images, split the list into 4 and start 4 scripts in parallel. Or start 2 jobs, one doing odd-numbered images and one doing even. Or somesuch... it depends what you are trying to achieve. – Mark Setchell Sep 24 '20 at 20:57
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222041/discussion-between-slyfox1186-and-mark-setchell). – slyfox1186 Sep 24 '20 at 21:26
  • Thanks for sharing your email. I sent you one a moment ago. Let me know what you think of my idea. – slyfox1186 Sep 24 '20 at 21:48

2 Answers2

3

With ImageMagick v7 you can get the dimensions of the image and apply them directly to any operation within that same command. Other than some command construction issues that others have mentioned, I'd suggest eliminating the "magick identify" part you use to get the dimensions, and instead put this right in the IM command...

... -thumbnail %[w]x%[h] ...

That simply substitutes the image dimensions for the "%[w]x%[h]".

Note: Those escape substitutions "%[w]" for width, height, etc. probably don't work with "mogrify". If you're only processing one image at a time at that point in your command you should be able to get exactly the same result with "magick !IMG! ..." and no "mogrify".

GeeMack
  • 4,486
  • 1
  • 7
  • 10
0

So I spent some more time with this because mogrify wouldn't work using the accepted answer. It also doesn't work well in batch scripts.

I found a way to grab the image dimensions for the -thumbnail option using tokens.

This will use a FOR command to find each jpg image in the script's folder, then it will use the command MAGICK identify to output info to stdout which the script will use the second FOR command and the third token to capture the image dimensions. The dimensions are stored inside the variable fsize.

So when each image is processed with mogrify it now has the original image's size dimensions automatically inserted.

@ECHO OFF
SETLOCAL
COLOR 0A
TITLE MOGRIFY JPG FILES FOR OPTIMAL QUALITY

PUSHD "%~dp0"

IF NOT EXIST "output" MKDIR "output"

SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%G IN (*.jpg) DO (
    SET "fname=%%G"
FOR /F "TOKENS=3" %%I IN ('MAGICK identify "!fname!"') DO (
    SET "fsize=%%I"
    CALL :RunMagick fname fsize
    :RunMagick
    MOGRIFY -monitor -path output/ -filter Triangle -define filter:support=2 -thumbnail "!fsize!" -unsharp 0.25x0.08+8.3+0.045 -dither None -posterize 136 -quality 82 -define jpeg:fancy-upsampling=off -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -define png:exclude-chunk=all -interlace none -colorspace sRGB -format jpg "*.jpg"
    )
)
EXIT /B

:END
ECHO.
ECHO SCRIPT COMPLETE
PAUSE>NUL
EXIT
slyfox1186
  • 301
  • 1
  • 13