Resizing Images in Node.js

Images in Node.js can be resized using the Sharp module.

This module is used to resize large images of any common file-type to web-friendly images of any dimension. This module claims to be multiple times faster than ImageMagick and GraphicsMagick.

Input Formats — JPEG, PNG, WebP, TIFF, GIF and SVG

Output Formats — JPEG, PNG, WebP and TIFF

All image properties, color spaces and transparency are handled correctly. Quality is also not sacrified for speed.

Installing SHARP

Sharp is an external module, it needs to be installed.

npm install sharp --save

Resizing by Height

The resize() function is responsible for resizing images. The return value is a Promise. This Promise when resolved successfully will pass an object containing various properties (like format, height, width etc) of the output image.

Resizing by height is achieved by passing the desired value of height as object to the resize function.

The width is automatically set according to the aspect ratio of the image.

const sharp = require('sharp');

let inputFile  = "img.jpg";
let outputFile = "output.jpg";

sharp(inputFile).resize({ height: 780 }).toFile(outputFile)
    .then(function(newFileInfo) {
        // newFileInfo holds the output file properties
        console.log("Success")
    })
    .catch(function(err) {
        console.log("Error occured");
    });

Resizing by Width

Just like above, in this case we provide the desired value of width. Height is automatically set according to the aspect ratio.

const sharp = require('sharp');

let inputFile  = "img.jpg";
let outputFile = "output.jpg";

sharp(inputFile).resize({ width: 1040 }).toFile(outputFile)
    .then(function(newFileInfo) {
        console.log("Success");
    })
    .catch(function(err) {
        console.log("Error occured");
    });

Resizing by Height and Width

When both height and width values are provided to the resize method, the image is squeezed in the provided dimensions. And as is obvious, the aspect ratio is not maintained.

sharp(inputFile).resize({ height: 1560, width: 1600 }).toFile(outputFile)
    .then(function(newFileInfo) {
        console.log("Success");
    })
    .catch(function(err) {
        console.log("Error occured");
    });

Sharp Offers More

You can do a lot more with sharp, like image rotation, flipping, sharpen, color manipulation etc. All these operations can be performed sequentially, like performing rotation first, resizing, and then converting it to grayscale.

Here is the complete resize API documentation.

Optimization using Streams

In case of large sized images, you can open an readable stream to the image, pipe it to sharp, and then pipe the sharp output to a file. This will save memory.

const sharp = require('sharp');
const fs = require('fs');

// input stream
let inStream = fs.createReadStream('img.jpg');

// output stream
let outStream = fs.createWriteStream('output.jpg', {flags: "w"});

// on error of output file being saved
outStream.on('error', function() {
    console.log("Error");
});

// on success of output file being saved
outStream.on('close', function() {
    console.log("Successfully saved file");
});

// input stream transformer
// "info" event will be emitted on resize
let transform = sharp()
                    .resize({ width: 711, height: 400 })
                    .on('info', function(fileInfo) {
                        console.log("Resizing done, file not saved");
                    });

inStream.pipe(transform).pipe(outStream);