Link to home
Start Free TrialLog in
Avatar of Bert Merayo
Bert Merayo

asked on

Search and Compress JPG files using batch in windows keeping the same filenames and file structure

I have a folder with a bunch of jpg and jpeg files that I need to compress. Using a simple batch file called compressall.bat with the following code:
@echo off
for %%f IN (*.jpg) DO magick -quality 12 "%%f" "%%f"
for %%f IN (*.jpeg) DO magick -quality 12 "%%f" "%%f"

Open in new window


I'm able to go into a directory and manually run this to compress down my image files in a folder on windows system. The magick command is part of the opensource tool imagemagick.

I have 18.282 folders to parse through all with different names. I know there has to be a scripted way of doing this operation.
Avatar of Bill Prew
Bill Prew

Are all the folders children of the same parent, meaning if we recursively processed all folders in the "tree" under a parent would that meet your need?


»bp
Hi Bert,

You may find this Experts Exchange article to be helpful:
Reduce the file size of many JPG files in many folders via an automated, mass, batch compression method

The article talks about GraphicsMagick, but if you prefer ImageMagick, that's fine, as they are similar (GraphicsMagick is a fork of ImageMagick and they retain many similarities).

If you want to see more usage of GraphicsMagick, check out these other EE articles:

Create a PDF file with Contact Sheets (montage of thumbnails) for all JPG files in a folder and each of its subfolders using an automated, batch method
Create an image (BMP, GIF, JPG, PNG, TIF, etc.) from a multi-page PDF
Convert a multi-page PDF file into multiple image files

Once again, almost everything in them will apply to ImageMagick, too. Regards, Joe
Avatar of Bert Merayo

ASKER

Yes, the same parent folder for all the child folders.
Working this quick, but should be close.  The FOR /R /D I added will enumerate all the subfolders under the base, and then we can run your original FOR loop on each of those, slightly modified.  We still need one other of your original FOR's to hit the base folder since the FOR /D ?R only hits children.

@echo off
setlocal

set BaseDir=c:\images

for %%f IN ("%BaseDir%\*.jpg" "%BaseDir%\*.jpeg") DO magick -quality 12 "%%f" "%%f"
for /d /r "%BaseDir%" %%A in (*.*) do (
    for %%f IN ("%%~A\*.jpg" "%%~A\*.jpeg" DO magick -quality 12 "%%f" "%%f"
)

Open in new window


»bp
Bill --

It works at the top level folder if there is an image there but it does not run against the images in the subfolders. The subfolders could be 2 to 3 folders deep.
Bill here is the tree of the test directory I'm working this out of. Thanks,

C:\images>tree /f
Folder PATH listing
Volume serial number is 3E67-0502
C:.
│   compressall.bat
│   IMG_0287-MTJ-000.JPG
│   magick.exe
│   test.bat

├───img1
│   │   IMG_0287-MTJ-000.JPG
│   │
│   └───img1_1
│       │   IMG_0287-MTJ-000.JPG
│       │
│       └───img1_2
│               IMG_0287-MTJ-000.JPG

├───img2
│       IMG_0287-MTJ-000.JPG

└───img3
        IMG_0287-MTJ-000.JPG
Can this be done easier in Powershell? I'm open to that if the batch file is not the right tool for this.
ASKER CERTIFIED SOLUTION
Avatar of Joe Winograd
Joe Winograd
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Can you be any more specific about what "does not work" means, any errors, or other display?


»bp
Joe, I tested this script earlier but it only compresses the parent folder image it does not touch the subfolder images.
Bill --

No errors, it processes the parent folder image but it does not touch the subfolder images.
Can you run this version and see what it displays.  It won't process any files, this is just a test, it will display the commands it would have executed.

@echo off
setlocal

set BaseDir=c:\images

for %%f IN ("%BaseDir%\*.jpg" "%BaseDir%\*.jpeg") do ECHO magick -quality 12 "%%f" "%%f"
for /d /r "%BaseDir%" %%A in (*.*) do (
    ECHO Subfolder="%%A"
    for %%f IN ("%%~A\*.jpg" "%%~A\*.jpeg" do ECHO magick -quality 12 "%%f" "%%f"
)

Open in new window


»bp
Reading the documentation it appears it might not handle full paths for the file names.  Can you also try a test of that from the command line, using the fully qualified path to one of the files to be converted in a folder and see what it does?


»bp
After a reboot of my PC , the last script you sent me Joe did the trick.  It does parse through all the folders and resises the image files as requested. Thank you! I will test further in a smaller group of files on my production network before I run it on 18,000 or so folders.
> I tested this script earlier but it only compresses the parent folder image it does not touch the subfolder images.

You did something wrong...maybe copied/pasted into the batch file incorrectly. I assure you that it works perfectly. Tested here many, many times...including two minutes ago on a parent folder with multiple-level subfolders...compressed every image in every subfolder!
Bill --

Your script gave me this error come to find out:

C:\image>test1.bat
The syntax of the command is incorrect.

C:\image>test1.bat

C:\images>setlocal

C:\images>set BaseDir=c:\images

C:\images>for %f IN ("c:\images\*.jpg" "c:\images\*.jpeg") DO magick -quality 12 "%f" "%f"

C:\images>magick -quality 12 "c:\images\IMG_0287-MTJ-000.JPG" "c:\images\IMG_0287-MTJ-000.JPG"
The syntax of the command is incorrect.

C:\images>)
Our messages crossed, Bert. I can't explain why a reboot would matter, but I'm glad that it worked for you! Regards, Joe
Thank you both Joe and Bill. I appreciate your time on this issue. It seems that my PC was not in gear during my testing.
Ah yes, I was pressed for time and missed a closing paren, see it highlighted below.

for %%f IN ("%%~A\*.jpg" "%%~A\*.jpeg") DO magick -quality 12 "%%f" "%%f"


»bp
You're very welcome, Bert, happy to help. Regards, Joe
Spoke to soon...It work on my test directory but in a small product set of files it comes back with this error:

mogrify: unable to open image '*.jpg': Invalid argument @ error/blob.c/OpenBlob/3485.

It repeats this over and over...
Joe --

This is the modified script:

@echo off
FOR /R "M:\530\MAS90\livestorage\SITE" %%G in (.) DO (
  PUSHD %%G
  magick.exe mogrify -quality 12 *.jpg
  POPD )

Open in new window


error is this --> mogrify: unable to open image '*.jpg': Invalid argument @ error/blob.c/OpenBlob/3485.
That just means that there aren't any JPG files in the subfolder. Ignore the message. It still works on every folder that contains JPG files.
For what it's worth, I pulled down ImageMagick and did a test here.  It can consume full pathnames on the command line, so no need for PUSHD/POPD.  I really despise those, but I won't go off on that.  At any rate, here is a slightly smaller version of Joe's script.

@echo off
FOR /R "M:\530\MAS90\livestorage\SITE" %%G in (.) DO magick.exe mogrify -quality 12 "%%~dpG*.jpg"

Open in new window


»bp
Hi Bill,
Are you sure that "%%~dpG*.jpg" is correct? Doesn't work here when I test with a root of "C:\images". But, in any case, the issue with "mogrify: unable to open image '*.jpg': Invalid argument @ error/blob.c/OpenBlob/3485" is simply that there are no JPG files in the folder...the error message may be safely ignored. Regards, Joe
Yes, that's the correct syntax, in a BAT file.  Works fine here...


»bp
Thanks Joe! I will try this again shortly and let you know what I get.
Sorry Joe, cut and paste error, really should be...

@echo off
FOR /R "M:\530\MAS90\livestorage\SITE" %%G in (.) DO magick.exe mogrify -quality 12 "%%~dpnxG\*.jpg"

Open in new window


»bp
> I will try this again shortly and let you know what I get.

OK, Bert. I'm confident that it works...just ignore the error messages, which will occur in any folder that has no JPG files.

> Sorry Joe, cut and paste error, really should be...

Nice, Bill...corrected one works perfectly!
Joe --

Ok, after letting this run for 40 minutes I get this error now a slight different one than the first one I gave you:

mogrify: UnableToOpenBlob '*.jpg': Invalid argument @ error/blob.c/OpenBlob/3485

I'm thinking I will need to let this run overnight and check back in the morning.  I did notice that the space on the drive is coming down by a few gigabytes. Thanks
Hi Bert,
I don't know why it is giving the "UnableToOpenBlob" error rather than the "unable to open image" error. It's probably for the same reason, i.e., no JPG files in the folder, but I'm not sure of that.

Good news that it's down by a few gigabytes...shows that the -quality 12 param is working to reduce file size. I'll check back into the thread in the morning to see how you're doing. Regards, Joe
We are down from 75.9 GB to 27.9, a very nice difference in hard drive space after the image compression. Everything worked out great.  Thanks again Joe!

Bert
75.9 GB to 27.9
Wow! Very nice! You're welcome, Bert, happy to help. Glad it worked out so well. Regards, Joe