71

I want to crop an image using command line tools only indicating pixels to crop for the four directions (the same way we can crop in LibreOffice)

For example:

crop image.jpg -top 5px -bottom 7px -right 14px -left 3px

Is there such a tool (not GUI)?

Zanna
  • 70,465
Maythux
  • 84,289

6 Answers6

81

Here is a workaround using convert from image magick pack.

sudo apt-get install imagemagick

For a picture image.jpg

$ identify image.jpg 

image.jpg JPEG 720x482 720x482+0+0 8-bit DirectClass 100KB 0.000u 0:00.009

As shown above, the input image is 720x482px.

Now to do cropping you have to determine two factors:

  1. starting point of the cropping (includes 2 directions)
  2. The cropped rectangle size (Here you can include the other directions)

Now back to the image image.jpg above, I want to crop:

  • top 5px
  • bottom 7px
  • right 14px
  • left 3px

then you could do it with (widthxheight+left+top / wxh+l+t format):

convert image.jpg -crop 703x470+3+5 output.jpg

Now

$ identify output.jpg 

output.jpg JPEG 703x470 703x470+0+0 8-bit DirectClass 102KB 0.000u 0:00.000
el-teedee
  • 157
  • 1
  • 12
Maythux
  • 84,289
  • 3
    It's said that Imagemagick 7 uses the "magick" command in place of "convert". If anyone run into command not found: convert issue, try magick – iplus26 May 04 '17 at 11:38
  • 1
    This was a big help, but took me a while to wrap my head around the "calculations". I had a set of 1280x1024 images I needed to crop top and bottom from, so final image would have the "middle" 718 pixels from the original (taking off a black band top and bottom). I needed to use this: convert in.png -crop 1280x718+0+152 out.png where I understand that line to mean: convert in.png -crop [final-right-x]x[final-right-y]+[crop-left]+[crop-top] out.png, although that doesn't seem to match @Maythux's numbers... FWIW! – Dɑvïd Feb 19 '18 at 10:11
  • 3
    Shouldn't it be 703x470 instead of 713x470? As the left+right cropping = 3+14 = 17px, that when subtracted from 720 is 703, and not 713. – Mooncrater May 31 '18 at 07:05
  • This helped! I also suggested an edit to FIX both 703px instead of 713px (which I agree to), and inverted left and top in format WxH+l+t – el-teedee Feb 26 '19 at 22:37
31

If you want to trim white regions away, imagemagick has a special command for it:

convert -trim input.jpg output.jpg
Martin Thoma
  • 19,277
16

To create a "user friendly" cli- option, the script below can be used. Simply run the command:

<script> <image> <crop_left> <crop_right> <crop_top> <crop_bottom>

It creates a cropped image of image.jpeg, named image[cropped].jpeg in the same directory.

The script

#!/usr/bin/env python3
import subprocess
import sys

# image, crop- dimensions
img = sys.argv[1]; left = sys.argv[2]; right = sys.argv[3]; top = sys.argv[4]; bottom = sys.argv[5]
# arrange the output file's name and path
img_base = img[:img.rfind(".")]; extension = img[img.rfind("."):]; path = img[:img.rfind("/")]
img_out = img_base+"[cropped]"+extension
# get the current img' size
data = subprocess.check_output(["identify", img]).decode("utf-8").strip().replace(img, "")
size = [int(n) for n in data.replace(img, "").split()[1].split("x")]
# calculate the command to resize
w = str(size[0]-int(left)-int(right)); h = str(size[1]-int(top)-int(bottom)); x = left; y = top
# execute the command
cmd = ["convert", img, "-crop", w+"x"+h+"+"+x+"+"+y, "+repage", img_out]
subprocess.Popen(cmd)

How to use

  1. The script uses imagemagick

    sudo apt-get install imagemagick
    
  2. Save the script above as crop_image (no extension) in ~/bin.

  3. Create the directory if necessary. In that case, also run source ~/.profile to make the directory show up in $PATH.
  4. Make the script executable.

Now simply run the script by its name, as mentioned, e.g.:

crop_image /path/to/image.jpg 20 30 40 50

Spaces are no problem, as long as in that case, you use quotes:

crop_image '/path/with spaces in the name/to/image.jpg' 20 30 40 50
Maythux
  • 84,289
Jacob Vlijm
  • 83,767
  • @Maythux Not sure what your latest edit means, you mean the solution above does not work on your system? It is cli only. – Jacob Vlijm Jun 04 '15 at 07:14
  • I'm sorry I was off three days ago, so I don't know why you get a downvote, instead here my +1 since you deserve. – Maythux Jun 08 '15 at 09:11
  • But I think even it works this would be pretty harder for a newbie a bit than using a native crop tool, but for me I love your way, pretty cool, sorry again for delay – Maythux Jun 08 '15 at 09:13
  • Wow, thanks. The downvote I got because of this: http://meta.askubuntu.com/questions/14082/how-much-data-does-the-system-need-to-detect-serial-down-votes – Jacob Vlijm Jun 08 '15 at 09:13
  • @Maythux while your answer is very well received :) – Jacob Vlijm Jun 08 '15 at 09:23
8

The crop command needs 4 things. To understand it take the image you want to crop. Now, imagine that on the image, you are drawing a rectangle of the size which you want to retain. The area outside this rectangle will be eliminated, cropped. The rectangle must not be tilted i.e. the top side must be horizontal.

Now, note down these 4 things:

  1. the width (W) in pixel of the rectangle
  2. height (H) of the rectangle
  3. distance of the left vertical side of the rectangle from the left margin/end (L) of the image
  4. distance of the top side of the rectangle from the top margin/end of the image (T).

Thus you have now W, H, L and T values. So far so good. To know the pixels, you may install krule tool in Ubuntu. Very useful.

Now, open the terminal and go to the folder where the image is stored. Use the following command and put the values of W, H, L and T properly:

convert input.jpg -crop WxH+L+T output.jpg
Zanna
  • 70,465
  • 1
    Not sure why this isn't the top answer. The whole reason I came here was to understand the encoding of the -crop <geometry> input, which everyone else just hand-waved over – Michael Altfield Aug 30 '20 at 12:22
5

Use mogrify -crop <W>x<H>+<X>+<Y> <files>.

Careful: the files are overwritten without notice. Add the -path option to specify an output directory to prevent this if required.

As an example: mogrify -crop 256x256+10+5 images/*.jpg will crop each image in the images folder to a 256x256 image by starting 10 pixels from the top and 5 pixels from the side. It will overwrite the old images.

If you get a Argument list too long error due to trying to convert many images at once, simply wrap your image path in single quotes to prevent bash from expanding it: mogrify -crop 256x256+10+5 'images/*.jpg' (mogrify will do the expansion itself)

joe
  • 129
R2-D2
  • 203
3

You can use convert command in image magick pack.
To install sudo apt-get install imagemagick or sudo yum install ImageMagick.
Then use -crop geometry to crop the image. For more readings read here