Compress image in Node JS

In this tutorial, we are going to teach you, how you can compress image in Node JS. You can download and install Node JS from their official site.

Video tutorial: Compress image in Node JS

First, create a new folder. Open CMD in it. And run the following commands:

> npm init
> npm install express http

Then, create a file named “server.js” and write the following code in it:

const express = require("express")
const app = express()
const http = require("http").createServer(app)

// [other modules]

const port = process.env.PORT || 3000

http.listen(port, function () {
	console.log("Server started running at port: " + port)

	// [post route goes here]

	// [get route goes here]
})

Then run the following commands in your terminal:

> npm install -g nodemon
> nodemon server.js

You will see a message saying the “Server started running at port: 3000”. You can access your server from the following URL:

http://localhost:3000

Now, we need to install the module for displaying views. And to get input from form fields. So, install the following modules:

> npm install ejs fs express-formidable

EJS module is used for displaying the HTML files. FS stands for File System, this module is used to handle files. And “express-formidable” is used for getting values from the input field. Make sure to run the “nodemon server.js” command again.

Install compress image module in Node JS

To install a module to compress image in Node JS, you need to run the following command in your terminal:

> npm install pngquant-bin@6.0.1 gifsicle@5.2.1 compress-images fs

Then, we need to include those modules in our project. So write the following lines in the [other modules] section:

const compressImages = require("compress-images")
const formidable = require("express-formidable")
app.use(formidable())

const fileSystem = require("fs")
app.set("view engine", "ejs")

Now, write the following lines in the [get route goes here] section:

app.get("/", function (request, result) {
	result.render("index")
})

After that, you need to create a folder named “views” at the root of your project. And in that folder, create a file named “index.ejs”. Following will be the code of “index.ejs”:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<title>Compress image</title>
	</head>

	<body>
		<form method="POST" action="/compressImage" enctype="multipart/form-data">
			<input type="file" name="image" accept="image/*" required />
			<input type="submit" value="Compress image" />
		</form>
	</body>
</html>

It will display a simple HTML form with an input field and a submit button. Then, you need to create a POST route that will handle this request. The following code goes in the [post route goes here] section of the “server.js” file:

app.post("/compressImage", function (request, result) {
    const image = request.files.image
    if (image.size > 0) {

        if (image.type == "image/png" || image.type == "image/jpeg") {
            fileSystem.readFile(image.path, function (error, data) {
                if (error) throw error

                const filePath = "temp-uploads/" + (new Date().getTime()) + "-" + image.name
                const compressedFilePath = "uploads/"
                const compression = 60
                
                fileSystem.writeFile(filePath, data, async function (error) {
                    if (error) throw error
                    
                    compressImages(filePath, compressedFilePath, { compress_force: false, statistic: true, autoupdate: true }, false,
                        { jpg: { engine: "mozjpeg", command: ["-quality", compression] } },
                        { png: { engine: "pngquant", command: ["--quality=" + compression + "-" + compression, "-o"] } },
                        { svg: { engine: "svgo", command: "--multipass" } },
                        { gif: { engine: "gifsicle", command: ["--colors", "64", "--use-col=web"] } },
                        async function (error, completed, statistic) {
                            console.log("-------------")
                            console.log(error)
                            console.log(completed)
                            console.log(statistic)
                            console.log("-------------")

                            fileSystem.unlink(filePath, function (error) {
                                if (error) throw error
                            })
                        }
                    )

                    result.send("File has been compressed and saved.")
                })

                fileSystem.unlink(image.path, function (error) {
                    if (error) throw error
                })
            })
        } else {
            result.send("Please select an image")
        }
    } else {
        result.send("Please select an image")
    }
})

The last thing you need to do is to create two folders named “uploads” and “temp-uploads” at the root of your project. Here, all compressed images will be stored.

This will compress the image up to 60%. You can now try to select an image from the input file and hit “Compress image”. You will see a success message if everything goes right. And you will see your compressed image in the “uploads” folder.

Real-world example

We implemented this compression in one of our projects, so you can get the real-world example of image compression in Node JS.

So that’s how you can compress an image in Node JS. If you face any problems in following this, kindly do let us know.

Download source code

[wpdm_package id=’1704′]