Graphics are the best way to communicate and when we talk about graphics first thing comes to our mind is Images! Be it a mobile application or any other web application, you will find images everywhere. Scale, Crop and Resize these are operations that are commonly performed on images and the real pain comes when we create API for the same. So in this article, we will basically scale, crop and resize images in Nodejs using Sharp.
Sharp is a high-performance Node.js image processing module, and the fastest module to resize JPEG, PNG, WebP and TIFF images. It useslibvipslibrary, which is nothing but an image processing library. This the fastest module available right now for image manipulation.
1. Creating a new Nodejs project and installing sharp
1. Let’s start off by creating a new Nodejs project by usingng init
command. This command will create a new package.json file.
2.you have to install the sharp nodejs module, to do that run the below command,
npm install sharp --save
Below is my package.json file for this application,
{ "name": "Image-manipulation-using-Sharp-Nodejs", "version": "1.0.0", "description": "Scale, Crop and Resize in Nodejs using Sharp", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Shashank Tiwari", "license": "ISC", "dependencies": { "body-parser": "^1.18.2", "dotenv": "^5.0.1", "express": "^4.16.2", "sharp": "^0.20.1" } }
2. Project architecture and Creating a NodeJs Server
To reduce the complexity of the code, I have separated each operation from each other. It will be very easy to understand when you will see the code for reference later.
Also, in this article, my primary focus would be to use the sharp module for scaling, cropping and rest of the operations. So we won’t go into details of how to create API and how to do server setup.
The above image is replicating the folders and files present in the application. In case if you want to learn how to master the setup of Nodejs project structure, I would recommend readingFolder Structure guideprovided by Rising Stack.
3. Cropping Images
With all that being said, let’s understand how can we use it in our Nodejs API. Here we won’t cover the entire code since it will make this article very lengthy. So I will only cover the code required to crop the images, as shown in below code,
route-handler.js:
/* * nodejs scale crop resize images sharp * @author Shashank Tiwari */ const height = parseInt(request.body.height, 10); const width = parseInt(request.body.width, 10); if (height === '' || height === null || height === undefined) { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : true, filepath : CONSTANTS.INVALID_HEIGTH }); } else if(width === '' || width === null || width === undefined) { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : true, filepath : CONSTANTS.INVALID_WIDTH }); } else { const imagePath = path.join(__dirname + '../../public/img/Jellyfish.jpg'); const outputImageName = 'cropped_output_' + height + '_' + width + '.jpg'; const outputImagePath = __dirname + '../../public/img/output/' + outputImageName; sharp(imagePath) .resize(height, width) .crop() .toFile(outputImagePath) .then( (ImageResult) => { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : false, filepath: outputImageName, message: CONSTANTS.SUCCESSFUL_MESSAGE }); }). catch( () => { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : true, message : CONSTANTS.SERVER_ERROR_MESSAGE }); }); }
Explanation:
- First, we have to extract the query parameter and based on that we will give input to the sharp library in order to crop the images.
- We have already stored an image on a server, named as Jellyfish.jpg. We will use this image to crop and resize. The
imagePath
variable refers to this stored image. outputImageName
variable holds the name of the cropped image,outputImagePath
will be the directory where we will store the cropped image.- Below that we have used sharp-function by providing the reference to an image. Now to crop the image you can do the method chaining and apply whatever operation this library offers.
- The below method will resize the image by specified height and width from the center of the image.
.resize(height, width)
Crop()
method will crop the image from the dynamically from the center of the image. You can read more on crop method from here..toFile()
method will create the image based on given image path..toFile(outputImagePath)
- And you are done cropping you can send the response from
.then()
method.
3. Scaling Images
In some web applications, there can be a situation you would like to scale the given image. The sharp library provides a very convenient way to this as well. To scale the image you can provide the height and width, depending upon the how you want to scale the image i.e. scale in or scale out.
The below code almost identical to the code written for the resizing except for the scaling images.
const width = parseInt(request.body.width, 10); if (height === '' || height === null || height === undefined) { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : true, filepath : CONSTANTS.INVALID_HEIGTH }); } else if(width === '' || width === null || width === undefined) { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : true, filepath : CONSTANTS.INVALID_WIDTH }); } else { const imagePath = path.join(__dirname + '../../public/img/Jellyfish.jpg'); const outputImageName = 'scaled_output_' + height + '_' + width + '.jpg'; const outputImagePath = __dirname + '../../public/img/output/' + outputImageName; sharp(imagePath) .resize(height, width) // Use resize otherwise it applies crop (From the Doc). .max() .toFile(outputImagePath) .then( (ImageResult) => { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : false, filepath: outputImageName, message: CONSTANTS.SUCCESSFUL_MESSAGE }); }) .catch( () => { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : true, message : CONSTANTS.SERVER_ERROR_MESSAGE }); }); }
Explanations:
- First few lines of the code are already familiar to us. So we will jump to the code where will scale the image.
- The first thing you have to do is give the height and width to resize method.
- After using
resize()
method use themax()
method. Themax()
method will make sure that your image ratio stays the same as before and it will resize the image to specified height and width. - Lastly, you have to use
.toFile()
to create a scaled image.
and that’s all you need to do.
3. Resizing Images
In a lot of web API’s/application resizing images is also a very common task. So why leave that, let’s see the code how to resize images using the sharp library. The below code is again almost same the previous two operations expect few lines.
/* * nodejs scale crop resize images sharp * @author Shashank Tiwari */const height = parseInt(request.body.height, 10); const width = parseInt(request.body.width, 10); if (height === '' || height === null || height === undefined) { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : true, filepath : CONSTANTS.INVALID_HEIGTH }); } else if(width === '' || width === null || width === undefined) { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : true, filepath : CONSTANTS.INVALID_WIDTH }); } else { const imagePath = path.join(__dirname + '../../public/img/Jellyfish.jpg'); const outputImageName = 'resized_output_' + height + '_' + width + '.jpg'; const outputImagePath = __dirname + '../../public/img/output/' + outputImageName; sharp(imagePath) .resize(height, width, { kernel: sharp.kernel.nearest }) .toFile(outputImagePath) .then( (ImageResult) => { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : false, filepath: outputImageName, message: CONSTANTS.SUCCESSFUL_MESSAGE }); }) .catch ( () => { response.status(CONSTANTS.SERVER_OK_HTTP_CODE).json({ error : true, message : CONSTANTS.SERVER_ERROR_MESSAGE }); }); }
Explanation:
- As always we have used sharp-function by providing the reference to an image.
- Then we have used
resize()
method withheight
andwidth
. Also along with height and width, there is the third parameter calledoptions
. - Using Options you can resize images in different variations.
- Read more about resizing images.
Conclusion
In this article, we studied how to Scale, Crop and Resize images in Nodejs using Sharp. Sharp Nodejs library is fast as compared to graphicsmagick, though I never tested it. But Reading their docs and hearing from other people over the internet, you can give it a try.
If you like this article, do share with others and also let me know if you have any problems while implementing it. Also, you can download the full source code of the application since I have just shared a piece of code here.
Nice and detailed article, thanks.
There is https://github.com/animir/node-rate-limiter-flexible package, which has almost the same options and much more.
Thanks for the article, it was very helpful.
Don’t take this as a personal attack, but you should learn how to indent your code.
I couldn’t read it.