Compress a PNG Image Size By Up To 75% With Node.js
In this article, we'll show you how to programmatically compress PNG images using Node.js.
We'll be using an NPM package called Imagemin that will do most of the heavy lifting for us. With that package, we'll implement the pngquant image compression library. The conversion we put the images through will reduce file sizes by as much as 75% and still keep your images looking good.
Before moving forward, make sure you have Node.js installed and an application directory setup for our code.
If needed, we wrote a guide on installing Node.js.
Let's get started!
Table of Contents
- Install NPM Packages
- Compress a Single PNG Image
- Compress Multiple PNG Images & Place Them in a New Directory
Install NPM Packages
Before we can start writing our code, we need to install both the imagemin and imagemin-pngquant NPM package.
The imagemin-pngquant NPM package is a Node.js implementation of the pngquant compression library and is a plugin for the imagemin NPM package.
You can install it with either NPM or Yarn:
NPM:
npm install imagemin imagemin-pngquant --save
Yarn:
yarn add imagemin imagemin-pngquant
When that's done installing, we're ready for the next step!
Compress a Single PNG Image
Now it's time to write some code!
Before writing and testing the code below, make sure you have an image that you want to compress in the root of your project directory. And also make sure you have a directory created for where the compressed image will be outputted to.
Once you have those two things set up, open your favorite text editor and add the code below to your Node.js file. We'll give you the full code and explain everything afterward.
Here's the full code:
const imagemin = require("imagemin");
const imageminPngquant = require("imagemin-pngquant");
(async () => {
const files = await imagemin(["your-image.png"], {
destination: "compressed-images",
plugins: [
imageminPngquant({
quality: [0.5, 0.6]
})
]
});
})();
There's a lot going on here, so let's break it down.
The first thing we do is import the imagemin
and imagemin-pngquant
NPM packages.
Then, we create a self invoked async function that our code will run inside. Inside of that, we use the imagemin()
function from the imagemin
NPM package, which takes an array of file path strings and an options object as parameters.
We pass the path to our PNG file (named "your-image.png"
) to the function. This is the image that gets compressed.
Inside the options object, we give the path to where we want the new file outputted to. And we also specify the imagemin
plugin we want to use when compressing the image. In this case, we are working with PNG images so the imagemin-pngquant
plugin NPM package will do the job.
After you run the code, the compressed image will be outputted to the compressed-images
directory or wherever you specified as your destination.
And if you look at the size of your new image, you'll notice it is much smaller than the original version. Also, notice that the image quality was not affected in any significant way.
Compress Multiple PNG Images & Place Them in a New Directory
In the last example, we only compressed one image at a time. But what if you have a whole directory of images you want to compress? In this section, we'll show you how to do that.
The assumption with the code below is that you have a directory named images
that holds one or more PNG images inside it. And that you have another directory named compressed-images
that you want to output your compressed images to.
For the code to work, make sure you have both directories created and add some PNG images
to the images directory.
Same as before, we'll give you the full code and explain everything afterward:
const imagemin = require("imagemin");
const imageminPngquant = require("imagemin-pngquant");
(async () => {
const files = await imagemin(["images/*.{png}"], {
destination: "compressed-images",
plugins: [
imageminPngquant({
quality: [0.5, 0.6]
})
]
});
})();
The code is identical to the previous example except for one line.
In the array of file paths parameter we pass to the imagemin()
function, we tell it to look for all PNG images in the directory named images
. The imagemin()
function will then recursively run the function for each PNG image in that directory.
After you run the code, all of the new images will be outputted to the compressed-images
directory or wherever you specified as your destination.
And if you look at the size of the new images, you'll notice they are much smaller than the original version. Also take notice that the image quality was not affected in any significant way.