Convert images from Windows Batch script

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
jobbe104
Posts: 1
Joined: 2017-02-06T03:18:11-07:00
Authentication code: 1151

Convert images from Windows Batch script

Post by jobbe104 »

Hi

This is my first post here, so hope my questions is ok.

We use Imagemagick for batch processing images before using them on our website.

We currently use the following:
convert input.jpg -resize 1300x1300 -quality 60 -strip -colorspace sRGB output.jpg

Our images come in various formats. Our website is optimized for handling images with proportions 3:2 in both landscape and portrait format, i.e. 1300x867 and 867x1300.

I would like to automate so that all images are automatically resized to have this proportion of 3:2 (it should cut off equally in top/bottom or left/right when cropping). Not sure if Imagemagick can figure out whether it is supposed to be an portrait image (height > width) or landscape image (width > height) and then make the crop to the 3:2 (or 2:3) format accordingly and after that resize to have a max width/height of 1300 px ?

Can anyone help ?

Thank you in advance

/Jacob
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Convert images from Windows Batch script

Post by Bonzo »

First a question; what version of Imagemagick are you using?

V7 can do calculation within the command whereas V6 can't. You will probably still need to do some checks to decide if the image is portrate or landscape.

This is some resize code I wrote a few years ago that could be adapted and could probably be shortened with V7:

Code: Select all

@echo off
Setlocal enabledelayedexpansion

:: Create the output folder if does not exist
MKDIR ".\modified" 2>NUL

:: Set maximium image height
SET /A "newHeight=780"

:: Set portrate extent width
SET /A "portrateWidth=390"

:: Set ratio, for a desired ratio of 0,6, enter 600
SET /A "ratio=600"

    :: Set the variable width to the image width
    For /F %%# in ('identify -verbose -ping -format "%%[fx:w]" "%1"') Do (SET /A "width=%%#")

    :: Set the variable height to the image height
    For /F %%# in ('identify -verbose -ping -format "%%[fx:h]" "%1"') Do (SET /A "height=%%#")

	:: Calculation for ratio
	SET /A "currentRatio=!width!*1000/!height!"

    :: Check if the photo is portrate or landscape and run the relavant code
	::Condition to meet, 500
	IF !currentRatio! GTR !ratio! (
    :: Only resize if height is over desired ratio
        IF  !height! LSS !newHeight! (
			IMconvert "%1" -verbose -trim ".\modified\%~n1.jpg"
		) ELSE (
			IMconvert "%1" -verbose -trim -resize x!newHeight! ".\modified\%~n1.jpg"
		)
    ) ELSE (

    :: Only resize if height is over 780
        IF  !height! LSS !newHeight! (
            :: Calculation for portrate extent width
            SET /A "newWidth=!height! * !ratio!/1000"
            IMconvert "%1" -verbose -trim -resize x!height! -background white -gravity center -extent !newWidth!x!height! ".\modified\%~n1.jpg"
        ) ELSE (
            IMconvert "%1" -verbose -trim -resize x!newHeight! -background white -gravity center -extent !portrateWidth!x!newHeight! ".\modified\%~n1.jpg"
        )
    )
PAUSE&EXIT
User avatar
GeeMack
Posts: 718
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: Convert images from Windows Batch script

Post by GeeMack »

jobbe104 wrote: 2017-02-06T03:26:51-07:00I would like to automate so that all images are automatically resized to have this proportion of 3:2 (it should cut off equally in top/bottom or left/right when cropping). Not sure if Imagemagick can figure out whether it is supposed to be an portrait image (height > width) or landscape image (width > height) and then make the crop to the 3:2 (or 2:3) format accordingly and after that resize to have a max width/height of 1300 px ?
Using IM 6 and Windows 10, a tiny BAT script like this should do just about exactly that...

Code: Select all

@echo off
setlocal

set INIMAGE="%~1"

convert ^
   %INIMAGE% ^
   -set filename:f "%%[t]_3x2" ^
   -write mpr:input ^
   -set option:distort:viewport "%%[fx:w<h&&w/2>h/3?h/3*2:w]x%%[h]" ^
   -distort SRT 0 ^
   -set option:distort:viewport "%%[fx:w>h&&w/3>h/2?h/2*3:w]x%%[h]" ^
   -distort SRT 0 ^
   -set option:distort:viewport "%%[w]x%%[fx:w<h&&w/2<h/3?w/2*3:h]" ^
   -distort SRT 0 ^
   -set option:distort:viewport "%%[w]x%%[fx:w>=h&&w/3<h/2?w/3*2:h]" ^
   -distort SRT 0 ^
   mpr:input ^
   -gravity center ^
   -composite ^
   -resize 1300x1300 ^
   -quality 100 ^
      "%%[filename:f].jpg"
Save it with a name something like "3x2crop.bat", then run it from a command prompt with any image file name as an argument. (Or even drag and drop image files onto the script in a file explorer or on a shortcut.)

Code: Select all

C:\path2script\3x2crop.bat someinputimage.jpg
It starts by creating an output file name made from the input file name with a "_3x2" inserted right before the extension. For example it will read the input file named "someinputimage.jpg" and create the output image "someinputimage_3x2.jpg".

Next it stores a copy of the input image in a temporary memory register.

Then it tests and reshapes the viewport according to one of the 4 (or 5 really) possible input ratio/orientation combinations. The result will be 3:2 if the input is W>H (or square, W==H). If the input is W<H the output will be 2:3. This will be more or less an output size/shape template.

The input image is brought back into the stack and composited over that properly proportioned viewport template. By setting "-gravity center" the composite effectively crops the maximum available 3:2 or 2:3 from the center of the original.

The "-resize 1300x1300" will resize any image so it fits within a 1300x1300 boundary while maintaining it's aspect.

Finish by setting the output JPG "-quality 100%" and send it to the output file name.

To run whole directories, just build a "for" loop around it.

This can be done twice as fast in half as many operations using IM7.
User avatar
GeeMack
Posts: 718
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: Convert images from Windows Batch script

Post by GeeMack »

GeeMack wrote: 2017-02-07T20:59:29-07:00This can be done twice as fast in half as many operations using IM7.
Something like this would work using ImageMagick 7 in a Windows BAT script...

Code: Select all

@echo off
setlocal

set INIMAGE="%~1"

magick ^
   %INIMAGE% ^
   -set filename:f "%%[t]_3x2" ^
   -gravity center ^
   -extent "%%[fx:w<h&&w/2>h/3?h/3*2:w]x%%[h]" ^
   -extent "%%[fx:w>h&&w/3>h/2?h/2*3:w]x%%[h]" ^
   -extent "%%[w]x%%[fx:w<h&&w/2<h/3?w/2*3:h]" ^
   -extent "%%[w]x%%[fx:w>=h&&w/3<h/2?w/3*2:h]" ^
   -resize 1300x1300 ^
   -quality 100 ^
      "%%[filename:f].jpg"
Just like my example for IM6 in the post above, it's really just a single IM command using a script variable to obtain the input file name. This one uses IM7, so the calculations can be done as FX expressions directly inside the settings for the "-extent ..." operations. Each one is a test to determine the aspect ratio and orientation, then a calculated crop if certain criteria are met, and no change otherwise. It doesn't require storing a separate copy of the original in memory, and there are no distort or composite operations. It's pretty fast and simple.
Post Reply