May
2007

Cropping multiple images the same way (short tutorial)

Sometimes you'll want to crop the same area from multiple images (think of taking the contents of the same window from a load of screenshots). Of course, you could fire up your favourite image editor to select and crop over and over, but, as usual, there is a better way. This short tutorial describes an efficient way to do this for a theoretically infinite amount of images.

Difficulty: Basic - Medium

Note: I strongly recommend making a backup of the images you're using for this tutorial before messing with them. Some actions in this tutorial will overwrite the image files, so if you make a mistake you may lose valuable data.

This tutorial assumes basic Linux knowledge, like starting a program, opening a terminal and working with a terminal.

The tools we'll be using are GIMP and mogrify (from the ImageMagick suite), so make sure that you have them installed. We'll use GIMP to graphically select the area to be cropped and the mogrify tool to automate the cropping, saving us a lot of work. Let's start with the selecting:

Getting the right cropping values using GIMP

In 5 steps:
Where to find the cropping values
1. Open up GIMP.
2. Open one of the images in GIMP.
3. Using the Rectangle Select Tool (hotkey "R"), select the area you want to be cropped.
4. Note the X, Y, Width and Height values GIMP gives you (have a look at the picture, you can find them in the GIMP main window).
5. Close GIMP (or leave it open if you plan to use it again soon).

We now have the values we need to tell the mogrify utility what to crop. Let's go on and write a line that'll execute mogrify in such a way that it'll crop all our images!

Cropping the images

Now we'll start working in the terminal. Open up your favourite one and cd to the directory where the images are located. Note that I strongly recommend having only the images that are to be cropped in the directory, nothing more. It saves you a lot of trouble. Well then, let's start with the mogrify command. The syntax for cropping is as follows:

[rechosen@localhost ~]$ mogrify -crop {Width}x{Height}+{X}+{Y} image.png

Now don't be scared, the {Width}, {Height} and so on simply are the places where you should put the values you got from GIMP! Note that I use a png file as an example, while mogrify is able to handle over 100 image file types. You don't have to use png files with it. Anyway, if I'd fill in the values from the screenshot, the mogrify command would look like this:

[rechosen@localhost ~]$ mogrify -crop 643x393+7+83 image.png

The logic behind this system is the following: crop an area of 643 by 393 pixels, starting at 7 pixels from the left and 83 pixels from the top of the image. Got it? Ok then. The above command would overwrite image.png with a cropped version. But this still manipulates just a single image. The easiest way to make mogrify modify all images is just this:

[rechosen@localhost ~]$ mogrify -crop 643x393+7+83 *.png

The asterisk makes bash fill in all png files in the current directory, and mogrify will handle them all happily. After a (hopefully short) wait, all the images will have been cropped. If you want to crop images of an other format, just change "*.png" to, for example, "*.jpg" or "*.gif".

You might want to give the cropped images other names, so that the original images will not be overwritten and it will be clear which images have been cropped and which haven't. This is more complex, but hey, we're working on Linux! Everything is possible if you take the time to write it.

Renaming the cropped images

In order to give the cropped images other names, we'll use a bash loop. This time, we'll use the convert utility. It is from the same family as mogrify, but it makes it easier for us to output to an other filename. I won't explain the whole loop, as most of it is bash knowledge, but I will tell you which things you can/should alter to get the right results. There are loops for two cases, just pick the one of which you like the file naming the most.

  • Case 1: You want the output files to be named like this: originalfile.png => cropped_originalfile.png (again, you can insert any of the over 100 supported image formats here, I just like png). The loop should be like this:

    [rechosen@localhost ~]$ for file in *.png; do convert -crop {Width}x{Height}+{X}+{Y} $file cropped_$file; done

    You should replace "png" with the extension you want (think of jpg, gif, png (of course) and so on), and the "{Width}", "{Height}" etc with the values you got from GIMP. You may also replace "cropped_" with any prefix you like.

  • Case 2: You want the output files to be named like this: originalfile.png => originalfile_cropped.png (or originalfile.jpg => originalfile_cropped.jpg, you name it). In that case, you should use the following loop:

    [rechosen@localhost ~]$ for file in *.png; do convert -crop {Width}x{Height}+{X}+{Y} $file ${file%.png}_cropped.png; done

    Again, replace "png" with the extension you want (watch it, there are 3 instances of it) and the "{Width}", "{Height}" etc with the values you got from GIMP. You can also replace "_cropped" with any suffix you like.

    Note that you can, in this case, easily modify the output format: if you want to output the cropped images in jpg format, you can just replace the third instance of "png" with "jpg", no matter what format your input files are. The convert utility will detect it and change the image format automatically.

Final words

Well, I hope this small tutorial helped you. If you want some (more) help with any of these things, feel free to place a comment. Thanks for reading and God bless!

11 Comments to “Cropping multiple images the same way (short tutorial)”

  • Martin March 10, 2009 at 20:37

    Topic: Weird cropping behavior

    If you are cropping a PNG and notice that the rest of the image is still present, but the viewport or canvas has shifted (which may not be noticeable if you use 'display' to see the image, but should be noticeable in 'gimp' if you have +x+y arguments to the crop), add ! (exclamation point) immediately following the geometry argument. This forces the crop to do as its name implies and crop rather than just moving the viewport. Other image formats don't have this viewport notion and therefore are properly cropped without the exclamation point.

    See http://www.imagemagick.org/script/command-line-options.php#crop for more info.

  • reza March 11, 2010 at 13:24

    Topic: Cropping multiple images the same way

    Very useful, thanks

  • Arulalan.T May 6, 2010 at 17:24

    Superb. Excellent. This example is helped me lot to crop my images. :-)

  • NareZ May 15, 2010 at 20:30

    good article! saved me a lot of time cropping 450+ pages :) thanks!

  • Max June 17, 2010 at 03:50

    Rechosen Thanks very much for the tutorial, it really helped make things easy as I had many files to crop in batch. This tutorial did the trick! Thanks very much again!!!

  • neilers January 16, 2011 at 10:18

    Hello there!

    Okay, i hope you could help me with this one.

    I want to create a custom Android live wallpaper out of a video i found on youtube. So far, i have managed to download the video, and convert each frame to a JPEG with 1280x720 resolution, same as the original.

    Now the custom live wallpaper creator has these prerequisites:
    1. files should be PNG
    2. files should be 800 x 480 (so i need to batch-crop it)
    3. files should be named n01.png, n02.png, ... , n100.png

    So far, With the help of your post ill be able to do number 2.. number 3, im not so sure.. is there a way to batch convert, batch crop and batch rename my files?

    thank you very much for any help!

    • rechosen January 16, 2011 at 11:42

      Hello neilers,

      You can satisfy all of those requirements in one line of bash. For number 1, you should know that the convert command detects the desired output format by name. So 'convert image.jpg outfile1.png' turns image.jpg into a png file named outfile1.png. For number 3, you can use the features of bash, namely variables. A batch rename could look like 'i=0; for file in *.jpg; do ((i++)); mv "$file" n$(printf "%02d" $i).jpg; done'. Combining everything means you get something along the lines of 'i=0; for file in *.jpg; do ((i++)); convert -crop {Width}x{Height}+{X}+{Y} "$file" n$(printf "%02d" $i).png; done'. Don't forget the exclamation mark from Martin's comment if you get those viewport problems. Hope this helps.

      Rechosen

  • Will Knight January 18, 2011 at 03:59

    Thanks, this tutorial has helped me a lot in cropping images at my work place.

  • HÃ¥vard Berland May 8, 2011 at 18:27

    If you want to this within Gimp, I managed this by importing each of the images to crop as separate layers. Then crop the image, effectively cropping all layers simultaneously. Then view each layer again, and export the image for each layer.

Post comment

Contact

Got a question? You can e-mail the author using the contact form.