Mogrify subfolders and keep original directory structure

3.9k Views Asked by At

I have files structure with subdirectories and image files inside. I want to use GraphicsMagick to convert image files to another format (and make them smaller). I can do it with simple command like this:

mogrify -path ../img-converted -format jpg ../content/*.jpg

But things get complicated, when I try to preserve subdirectory structure. Mogrify doesn't have this option, so I need to write shell script to check all directories (and maybe create new ones).

How this should be done?

3

There are 3 best solutions below

1
On

Supposing Windows OS as question tagged batch-file.

At first, using robocopy to copy all subfolder structure from source folder to the destination one. Then, looping through source folder and recurse it's subfolders, get full source and target (sub)paths and echo them. As not sure in mogrify using therefore @echo mogrify ... formulated in terms of my (mis)understanding it...

@ECHO OFF >NUL
@SETLOCAL enableextensions enabledelayedexpansion
set "source=content"
set "target=img-converted"
robocopy %source% %target% nonexistingfilename /E
FOR /R "content" %%G in (.) DO (
  set "sourcefldr=%%~dpnxG"
  set "targetfldr=!sourcefldr:%source%=%target%!"
  @echo !sourcefldr!    !targetfldr!
  if EXIST "!sourcefldr!\*.jpg" (
    @echo mogrify -path !targetfldr! -format jpg !sourcefldr!\*.jpg
    rem surround pathnames with double quotes if necessary as follows
    rem mogrify -path "!targetfldr!" -format jpg "!sourcefldr!\*.jpg"
  )
)
@ENDLOCAL
@goto :eof

That nonexistingfilename (could be replaced with ^Nul) in

robocopy %source% %target% nonexistingfilename /E

command assures copying folder structure only, no files. Using *.jpg instead will copy all *.jpg as well:

robocopy %source% %target% *.jpg /E

0
On

The existing Windows answer gives only a single file at a time to mogrify, which probably slows it down since it cannot multithread with OpenMP in the same way.

Here is my answer for a batch script. It mogrifies all matching files in the current directory, and then also in all subdirectories (recursively). Save the batch script in your desired directory and then execute it.

@echo off
echo MOGRIFY CURRENT DIRECTORY:
@echo on
magick mogrify -transparent white -trim +repage *.png
@echo off
echo:
echo MOGRIFY SUBDIRECTORIES:
@echo on
FOR /D /R %%A IN (*) DO magick mogrify -transparent white -trim +repage "%%A\*.png"
@echo off
echo:
echo SCRIPT COMPLETE
pause
0
On

This worked for me - it resizes all jpg files in the current folder and all subfolders, while preserving the folder structure:

find -iname '*.jpg' -exec mogrify -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG -colorspace sRGB -resize '2560x2560>' {} +