Code Review Videos > Linux > How do I resize an image in ImageMagick command line?

How do I resize an image in ImageMagick command line?

Five days a week I ride my bike. A lot of those days are done indoors, on what is a very nerdy exercise bike setup. There’s a bit more too it than that, and if you are at all interested, have a read of (one of) my other blog(s) over at CyclingIndoors.co.uk.

Why that’s relevant to this post is that as part of that blog, I take many, many screenshots.

Depending on the cycling program I use, depends on the immediate usability of the screenshot that Windows produces.

One of the cycling training programs I use is called MyWhoosh. That’s an Unreal Engine game that runs as a Windows App somehow. I don’t quite know the specifics, but essentially it’s like a full screen app that doesn’t go truly full screen like a typical game.

What that does mean is that when I get screenshots out, they look like this:

weird image size before resize imagemagick

Each image comes out at 5040×2160, which is a hazard of the rather odd monitor setup I have.

Aside from being a weird shape, they are also huge:

large image size before resize imagemagick

So really, I have two problems:

  1. Crop the image to remove the unwanted second display
  2. Resize the cropped image to something roughly 800 pixels wide

Before Resizing An Image Using ImageMagick

Before resizing an image using ImageMagick, it is worth me stating a couple of obvious, yet easily overlooked things.

Install ImageMagick

The first is you will need Image Magick to complete this task 🙂

# ubuntu

sudo apt update
sudo apt install imagemagick

# osx

brew install imagemagickCode language: Shell Session (shell)

Pretty straightforward.

Weirdly though, once installed you don’t run it using imagemagick or whatever. Instead you use convert, e.g.

➜  ~ convert --version

Version: ImageMagick 6.9.11-60 Q16 x86_64 2021-01-25 https://imagemagick.org
Copyright: (C) 1999-2021 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP(4.5) 
Delegates (built-in): bzlib djvu fftw fontconfig freetype heic jbig jng jp2 jpeg lcms lqr ltdl lzma openexr pangocairo png tiff webp wmf x xml zlib
Code language: Shell Session (shell)

That’s the kinda obvious step.

Backup Your Images

The less obvious, but no less important step is to take a quick backup / copy of your images.

Cropping and resizing images via the command line are destructive operations, and there’s no easy way to undo them.

I just whack a copy of them in a sub folder. Do whatever you want though, I’m not your dad.

Cropping Your Images Using ImageMagick

Before I can resize the images, in my case I first need to crop off that second screen.

You may not need to do this, but it’s interesting to show anyway.

The way I do this is to use Photopea.com to get the measurements:

Got to laugh at how bad that is.

The gist of this is, drag and drop your image into photopea.com.

Photopea is like Photoshop, except it runs in the browser. Pretty amazing.

Then use the box selector thing – highlighted with the red arrow in the screenshot above.

As you drag you should see a box with X and Y co-ordinates display. You may be OK with rough co-ordinates. I probably should have known I was wanting a 3840×2160 crop, as that is a 4K resolution.

If you don’t see the co-ords, you can click on the layer on the right, then click the little lines (the top green circle), and then that should show you the selection bounds.

Things get a little more complex if this is your middle screen, but thankfully in my case the screen I want will start at pixel 0, and then go across to 3840.

Hopefully that makes sense. I suspect if you’re doing this sort of thing, it probably will.

ImageMagick Crop Command Example

OK, so the command to crop off the second monitor using ImageMagick is as follows:

# generic command
convert input.jpg -crop 3840x2160+0+0 output.jpg

# my specific command
convert 'Screenshot (264).png' -crop 3840x2160+0+0 output.jpgCode language: Shell Session (shell)

Replace input.jpg with the name of your input image and output.jpg with the desired name for the cropped image.

The 3840x2160 part specifies the dimensions of the cropped region, and +0+0 indicates the starting point at the top-left corner of the image.

This command will crop the image to a size of 3840×2160 pixels, starting from the top-left corner.

If you want to specify a different starting point or need to crop from a different location within the image, you can adjust the +X+Y values accordingly, where X is the horizontal offset, and Y is the vertical offset from the top-left corner.

For example, if you want to start the crop from the point (500, 300) and crop to 3840×2160, you would use:

convert input.jpg -crop 3840x2160+500+300 output.jpgCode language: CSS (css)

So far, so good.

Now we have the cropped image:

image magick cropped image result

Of course I have already shrunk that image massively because right now it’s still 10mb:

directory contents after shrinking with image magick

This is kind of a ‘proof of concept’ still at this stage.

We have done part one.

Let’s now resize the image using image magick.

Resizing An Image With Image Magick

Resizing an image with ImageMagick is no more difficult than cropping an image.

We’re going to shrink our images down to a friendly 1024×768, because I am going very hard of sight in my old age.

To resize the cropped image to a new size of 1024×768, you can use the convert command again with the -resize option. Here’s the command:

convert cropped_image.jpg -resize 1024x768 resized_image.jpgCode language: Shell Session (shell)

Replace cropped_image.jpg with the name of your cropped image and resized_image.jpg with the desired name for the resized image. This command will resize the cropped image to the specified dimensions of 1024×768 while maintaining its aspect ratio.

If you want to force the image to exactly 1024×768, potentially distorting its aspect ratio, you can add an exclamation mark ! to the -resize option like this:

convert cropped_image.jpg -resize 1024x768! resized_image.jpgCode language: CSS (css)

This will resize the image to exactly 1024×768 pixels, potentially stretching or compressing it to fit the new dimensions.

You can also do this by percentage, if so desired:

convert cropped_image.jpg -resize 10% resized_image.jpgCode language: CSS (css)

This command will resize the image to 10% of its original dimensions while maintaining its aspect ratio.

A Quick Recap

So far we have two stages, one to crop the original image, and then another to resize the cropped image.

This takes the file size from 154.mb to 271.3kb.

Pretty good.

➜  1 convert 'Screenshot (264).png' -crop 3840x2160+0+0 cropped.jpg

➜  1 convert cropped.jpg -resize 1024x768 resized.jpg    
          
➜  1 ls -la

total 17724
drwxrwxr-x 3 chris chris    20480 Sep 16 17:16  .
drwxrwxr-x 3 chris chris    16384 Jun 29 15:14  ..
drwxrwxr-x 2 chris chris     4096 Sep 16 16:36  backup
-rw-rw-r-- 1 chris chris  2458013 Sep 16 17:17  cropped.jpg
-rw-rw-r-- 1 chris chris   271294 Sep 16 17:17  resized.jpg
-rw------- 1 chris chris 15364104 Sep 16 15:58 'Screenshot (264).png'Code language: Shell Session (shell)

But now I need to apply this same set of actions to a batch of images.

How can I do that?

Batch Resizing Images Using ImageMagick

What if you have a number of images that you need to both crop and resize?

I happen to have a directory of 12, and I’m too lazy to do this process for each.

Let’s make the computer work for us:

for file in ./*.png; do
    # Get the base filename without the directory and extension
    filename=$(basename -- "$file")
    filename_without_extension="${filename%.*}"

    # Crop the image and save it with "_cropped" suffix
    convert "$file" -crop 3840x2160+0+0 "./${filename_without_extension}_cropped.jpg"

    # Resize the cropped image and save it with "_resized" suffix
    convert "./${filename_without_extension}_cropped.jpg" -resize 1024x768 "./${filename_without_extension}_resized.jpg"
doneCode language: Shell Session (shell)

You can copy / paste that directly into your terminal and it should run for your current directory, creating something like this:

batch imagemagick crop and resize output

This is pretty handy, but as a one liner (split over multiple lines for readability) we are really pushing our luck here.

For this kind of thing, in reality, I would create a shell script.

#!/bin/bash

# Directory where the original images are located
input_dir="./"

# Directory where the resized images will be saved
output_dir="./resized/"

# Check if the 'resized' directory exists; if not, create it
if [ ! -d "$output_dir" ]; then
    mkdir -p "$output_dir"
fi

# Loop through all PNG files in the input directory
for file in "$input_dir"*.png; do
    if [ -f "$file" ]; then
        # Get the base name of the file (without extension)
        base_name=$(basename -- "$file")
        base_name_no_extension="${base_name%.*}"

        # Crop and resize the image
        convert "$file" -crop 3840x2160+0+0 -resize 1024x768 "$output_dir$base_name_no_extension.jpg"
    fi
done

echo "Done!"Code language: Shell Session (shell)

If you do it this way, create a file named something like batch.sh and copy / paste that script in.

Then be sure to save, and make the script executable with chmod +x batch.sh.

Then run it with sh batch.sh.

batch script to resize image with image magick

And there we have it.

Now you can easily resize one or one thousand images using ImageMagick.

paul daniels thats magic

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.