Image manipulation is a common task that developers come across. Uploaded images may need to be cropped, resized, compressed, etc. on the server before being saved off in a storage service like S3.

There are numerous cloud services that provide operations like these as-a-service, such as Cloudinary. However, with GraphicsMagick, it really isn’t that hard to wire up tasks like these for ourselves. And as Javascript Developers, we get to work with GraphicsMagick right in our NodeJS environment thanks to the gm npm module 🎉.

What is GraphicsMagick?

GraphicsMagick provides a comprehensive collection of utilities, programming interfaces, and GUIs, to support file format conversion, image processing, and 2D vector rendering.

What we’ll be building today is a simple Express application that takes the operation (resize or crop) and some additional information, performs the operation on an image that is stored on the server and returns the final image to the client in the response.

Note: Before we get started, we need to install GraphicsMagick. You can follow the installation guide(s) for your operating system here.

Setting up the Server

Let’s quickly bootstrap an ExpressJS application.

Cropping images

To crop images, we can use the gm library’s crop API, which takes the width and height to crop (and optionally the specific x and y coordinates around which you want to crop).

Here’s an example of how the crop API works. 🤓

Now, to crop an image in our demo application, we need the height and width of the cropped area. Let’s get this information via request parameters in the endpoint url. We can open up an endpoint /crop/:width/:height - for example, hitting the endpoint /crop/300/400 will load the image from the filesystem, crop it to 300x400 and then return the cropped image.

While the above works, you’ll notice that it crops from a corner. If you want to crop around the center, you can use the gravity API that gm provides to gravitate the starting position.

Resizing Images

To resize images, we can use the resize API. Resizing can be done in two ways — resizing while maintaining the aspect ratio and resizing while not maintaining the aspect ratio.

The resize method takes two main parameters, a width and a height. If either the width or the height is set as null , then the image is resized to the specified width or height, while maintaining the aspect ratio. However, if both width and height are provided, the resizing would break out of its aspect ratio and resize to the given width and height.

Show me the code! Ok ok, here’s an example of how the above would work. 🤓

Now, let’s extend our demo application to resize images too. Let’s open up a new endpoint /resize/:width/:height . This endpoint will take the width and height from the request parameters again and resize the image — for example, hitting the endpoint /resize/300/200 will load the image from the filesystem, resize it to 300x200 and then return the resized image.

And that’s all folks! 🚀