How to compress images in Node.js using Sharp

Compressing images for the web or in apps can greatly improve performance. Sharp will help you compress images in Node.js easily.

Compressing images for the web or in apps can greatly improve performance. Sharp will help you compress images in Node.js easily .

How to compress images in Node.js using Sharp Picture 1How to compress images in Node.js using Sharp Picture 1

Unnecessarily large images can slow down response times, waste bandwidth, and create a sluggish user experience, especially for those on limited network plans. This leads to fewer bounce rates or page transitions on the web.

Compressing images before uploading them can minimize these problems and provide a better user experience. The Sharp module makes this process quick and easy.

Set up the development environment

To illustrate the image compression process, start by setting up an image upload service using multer. You can speed up this process by cloning the desired template from the GitHub repository.

After cloning the GitHub repository, run this command to install the image upload service image dependencies:

npm install

Next, install Sharp by running this command:

npm install sharp

The Sharp module is a high-performance Node.js library for image processing and manipulation. You can use Sharp to effectively resize, crop, rotate, and perform other operations on photos. Sharp also has excellent support for image compression.

Image compression techniques for different formats

JPG/JPEG

JPEG is an image compression standard developed by the Joint Photographic Experts Group to compress photorealistic photographs using progressive tones and color gradients. It uses the term lossy compression, creating smaller files by eliminating some image data.

To compress JPEG images with Sharp, import the Sharp module and pass filePath or a buffer of images as an argument. Next, call the .jpeg method on the Sharp instance. Then, pass a configuration object with a quality property that takes a number between 0 and 100 as its value. In particular, 0 returns the smallest compressed image with the lowest quality, while 100 returns the highest compressed image with the best quality.

You can set the value according to your needs. If you want the best image compression results, keep the value between 50-80 to achieve a balance between size and quality.

Finish the job by saving the compressed image to the file system using the .toFile method . Pass the file path you want to write as an argument.

For example:

await sharp(req.file.path) .jpeg({ quality: 60 }) .toFile(`./images/compressed-${req.file.filename}`) .then(() => { console.log(`Compressed ${req.file.filename} successfully`); });

The default value for quality is 80 .

PNG

PNG is an image file format for lossless compression and support for transparent backgrounds.

Compressing a PNG image with Sharp is similar to compressing a JPEG image with Sharp. However, there are two changes you need to make when the photo is in PNG format.

  1. Sharp processes PNG images using the .png method instead of .jpeg .
  2. The .png method uses compressionLevel , which is a number between 0 and 9 that replaces quality in the configuration object. 0 gives the fastest and largest compression value possible, and 9 gives the slowest and smallest compression value.

For example:

await sharp(req.file.path) .png({ compressionLevel: 5, }) .toFile(`./images/compressed-${req.file.filename}`) .then(() => { console.log(`Compressed ${req.file.filename} successfully`); });

The default value for compressionLevel is 6 .

Other formats

Sharp supports compression in various image formats, including WebP, TIFF, AVIF, HEIF.

Compress images with Sharp

If you have cloned the GitHub repository, open the app.js file and add the following imports.

const sharp = require("sharp"); const { exec } = require("child_process");

Excel is a function provided by the child_process module, which allows you to deploy shell commands or an external process from a Node.js application.

You can use this function to run a command to compare file size before and after compression.

Next, replace the POST handler ' /single ' with the code block below:

app.post("/upload-and-compress", upload.single("image"), async (req, res) => { try { if (!req.file) { return res.status(404).send("Please upload a valid image"); } const compressedFileName = req.file.filename.split(".")[0]; const compressedImageFilePath = `./images/${compressedFileName}-compressed.png`; await sharp(req.file.path) .jpeg({ quality: 50 }) .toFile(compressedImageFilePath) .then(() => { let sizeBeforeCompression, sizeAfterCompression; const sizeBeforeCompressionCommand = `du -h ${req.file.path}`; const sizeAfterCompressionCommand = `du -h ${compressedImageFilePath}`; exec(sizeBeforeCompressionCommand, (err, stdout, stderr) => { sizeBeforeCompression = stdout.split("t")[0]; exec(sizeAfterCompressionCommand, (err, stdout, stderr) => { sizeAfterCompression = stdout.split("t")[0]; res.send({ message: "Image uploaded and compressed successfully", sizeBeforeCompression, sizeAfterCompression, }); }); }); }); } catch (error) { console.log(error); } });

The above code block implements the JPEG image compression technique and compares the size before and after using the du command .

The du command is a Unix utility, short for 'disk usage'. It estimates file space and analyzes disk usage in a folder or group of folders. When you run the du command with the -h flag , it shows the file size that each subdirectory uses along with the content in human-readable form.

Start the upload service by running this command:

node app.js

Next, test the application by sending the JPG image to the localhost: /upload-and-compress route using the Postman app client or any other API testing tool.

You will see a response similar to this:

{ "message": "Image uploaded and compressed successfully", "sizeBeforeCompression": "13M", "sizeAfterCompression": "3.1M" } 

Above is how to compress images in Node.js using Sharp . Hope the article is useful to you.

4 ★ | 1 Vote