Welcome to the most active Linux Forum on the web.
Go Back > Blogs > linux-related notes
User Name


Just annotations of little "how to's", so I know I can find how to do something I've already done when I need to do it again, in case I don't remember anymore, which is not unlikely. Hopefully they can be useful to others, but I can't guarantee that it will work, or that it won't even make things worse.
Rate this Entry

Batch-cropping with ImageMagick + GIMP. Script helper(s), in development

Posted 12-09-2017 at 03:21 PM by the dsc
Updated 12-14-2017 at 12:01 PM by the dsc (mumbling about possible improvements)

Here's the explanation:

These are the original images to be cropped in batch, all jpegs, all in the same folder:

(It's a single image here, but these are in fact separate files)

The next step is to create a montage (still done manually):

montage -define jpeg:size=220x -geometry 220x220 *.jpg montage1.png

And then it's edited on GIMP: gimp montage1.png

On GIMP, you create a new, transparent layer over the montage, and make those squiggles over the points of interest. Here's how it looks:

(You can also use proper filled-in rectangles, if you're so inclined. Or even ellipses, but the cropped image will be the the largest rectangle where that ellipse/all marks fit)

You can tweak the transparency of the squiggle-mask layer if that's more convenient, but it's possibly ideal to restore full opacity after finishing. But maybe the "threshold 90%" manages to deal with it regardless, I haven't yet tested. (Edit: now I've tested. It wasn't working with transparency before, so I made some tweaks and apparently now you can "forget" or not care about the transparency, and it will work.)

Then you toggle the visibility of the montage itself, leaving you only with the squiggles over a transparent background (still "real transparency", rather than ImageMagick's black and white, the script takes care of that for simplicity), and you export them as "montage.png", on the same folder.

You run the script, wait a while (it's slower than I'd expected, I think I'm piping too much stuff, possibly there are more adequate ImageMagick syntaxes to produce the same results, faster - EDIT: now it's possibly doing it pretty much close to the most efficient way possible ), and the result is:

(Again, only shown here as a single image, but they're separate files, cropped from the originals)

If you think you can somehow grasp the logic and/or improve the code, and better yet, somehow embed it into GIMP as a python-fu/script-fu/lua-fu(?) thingie, you're welcome to do it! ...If anyone really thinks this kind of method of cropping is a good idea. I'm surprised there isn't already a GUI that does it, so I guess there's not so much demand for it.

Here's where it started:

The "latest version" (still an horrific mess, only somewhat better than the previous one):

# This script does the cropping after the mask layer (montage.png) has already been saved
# This is script is free/public domain, and there are no warranties whatsoever
# Thanks to fmw42, "Fred" from "Fred's ImageMagick Scripts"

convert="nice -18 convert"

$convert montage.png -crop 220x220 +repage maskplain-%05d.png

\ls -1 *.jpg > originals.txt
\ls -1 maskplain*.png > masks.txt

while read original <&3 && read mask <&4 ; do 

    res=($(identify -format  "%w %h" {$original}))


    if ((x>y)) ; then



    ((y>x)) && samplevar="x${y}"

    unset cropmask

    if ! ((x==y)) ; then

        cropmask="-crop $cropmaskvar"


    $convert ${mask} -colorspace gray -background white -alpha remove -threshold 99% -sample ${samplevar} $cropmask +repage /dev/shm/masktmp-${original}.gif

    cropv=`$convert /dev/shm/masktmp-${original}.gif  -format "%@" info:` ; 

#$convert "${original}" -crop $cropv +repage "${original/.jpg/-cropped.jpg}"
    # I have found that for the final crop, jpegtran does an incomparably faster job than imagemagick. This line will attempt first to do a lossless cropping, and proceed to a normal cropping, if it fails.
     jpegtran -perfect -crop $cropv -outfile "${original/.jpg/-cropped.jpg}" "${original}" || jpegtran -crop $cropv -outfile "${original/.jpg/-cropped.jpg}" "${original}"

done 3<originals.txt 4<masks.txt
And leaves a lot of thrash all around. Gifs on the current folder, and at least one in /dev/shm. I don't know how portable /dev/shm is in Apple and whatever other Linux-type OSs where it could be used. Even in Linux, some scripting equivalents to grammar-nazis will say one shouldn't create temporary files there.

An interesting improvement on the whole logic would be to have the montage and "de-montage" operating with some added padding over the original images. That would allow more freedom to crop very close or exactly at the border of an image, without touching the neighboring one, affecting its crop marks (also making it crop all the way to the touched border).

That requires some more thought than just adding the padding to the montage command, and whatever would be the reverse of that for the crop.

Edit: changed the "demontage" to add more padding zeroes. When working with many images, just two zeros can mix up the file sequence. Which is something unreliable to begin with.
Posted in Uncategorized
Views 256 Comments 0
« Prev     Main     Next »
Total Comments 0




All times are GMT -5. The time now is 07:16 AM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration