Node.js has many packages for processing images. You can use the image-size
package to get the image width and height. There are many reasons for extracting the dimensions of an image.
You can use them to validate your image file before uploading it to the server. I will show you how to integrate this package with an Express server.
In this blog post, we will go through different ways of using the image-size
package. This is a step-by-step guide for you.
How to Get Image Dimensions in Node.js
In order to find the dimensions of an image file, you need to follow these steps:
Step 1: Generate a package.json file
To initialize a Node.js project, you need to have a package.json file inside your project folder. Open your terminal in your project folder and run the following command to generate a package.js file.
npm init
It will ask for some information about your project. Provide that information, don't worry you can update them in your package.json file later if necessary.
If you don't want to answer a question, press enter
on your keyboard. But you can also use the -y
flag if you want to generate the package.json file with all the default answers.
npm init -y
Also Read: How to Get Any File Size in Node.js: Mastering the fs Module
Step 2: Install the image-size Package
As we will use the image-size
package, we have to install this in our project. Run the following command to install it as the project dependency.
npm install --save image-size
If you are using the yarn
package manager, run this:
yarn add image-size
Step 3: Import image-size Package
Before using this package, you need to import it into your JavaScript file. Add the following code in your file for importing the image-size
package.
const imageSize = require('image-size')
It will give you a default function. You can give any name you want to this imported function.
Step 4: Find the Image Width and Height
The imageSize()
function takes the path of an image as a string. When you call this function with an image file path, it will return an object. This object will contain the width and height values as its property.
Synchronous
const imageSize = require('image-size')
try {
const dimension = imageSize('./images/banner.jpg')
console.log(dimension.width) // Image width
console.log(dimension.height) // Image height
} catch (error) {
// Handle error here
console.log(error)
}
I have an image called banner.jpg
inside the images
folder. I am passing the path of this file to the imageSize()
function. The dimension
object has width
and height
properties.
Here I am calling this function synchronously. The main disadvantage is that it will block the main thread of JavaScript. If you use it in a Node.js server, this might reduce the performance of your server.
That's why it is better to call this function asynchronously.
Also Read: Synchronous VS Asynchronous Programming with Examples
Asynchronous
You can call the imageSize()
function provided by the image-size
package asynchronously with a callback function. Then it will process the image file without blocking the main thread.
const imageSize = require('image-size')
imageSize('./images/banner.jpg', (err, dimension) => {
if (err) {
console.log(err)
return
}
console.log(dimension.width) // Image width
console.log(dimension.height) // Image height
})
In this case, The imageSize()
function takes the file path as the first argument and a callback function as the second argument.
The callback function has two parameters: err
, which is an error object if an error occurs during the process, and dimension
, which is an object that contains the width and height of the image if the process is successful.
Use image-size Package with Promises
If you don't like to use it with callback functions, you can also use it with promises. For that, we can make use of the promisify
function from the util
package provided by NodeJS.
The promisify
function is used to convert callback-based functions into Promise-based functions. This is useful when we want to use functions that follow the traditional Node.js callback pattern, but we want to work with Promises instead.
const { promisify } = require('util');
const imageSize = promisify(require('image-size'));
(async () => {
try {
const dimension = await imageSize('./images/banner.jpg')
console.log(dimension.width)
console.log(dimension.height)
} catch (error) {
console.log(error)
}
})();
I am importing the image-size
package and passing it to the promisify()
function to convert the imageSize()
function into a promise-based function.
Here I am defining a self-invoking function to use async/await syntax with the promise. Use a try...catch
block to handle any unexpected errors.
Now you can call the imageSize()
function with the image path and add the await
keyword to wait for the promise to resolve and retrieve the dimensions of the image.
How to Get Image Width and Height in Express Server
Most of the time, we want to file the image dimensions inside our servers. If you are using express in your Node.js server, you can easily use this image-size
package.
// server.js file
const express = require('express')
const appRoutes = require('./routes')
const app = express()
// Adding routes
app.use(appRoutes)
const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
console.log(`Server is running at port ${PORT}`)
})
First, I am setting up an Express server for my example. I am importing my routes from routes.js
file and adding them to the server.
I will use the multer
package to retrieve and process the uploaded image file from the req
object. You can learn more about this package and how it works from its official documentation.
const multer = require('multer')
const express = require('express')
const { promisify } = require('util')
const { unlink } = require('fs/promises')
const imageSize = promisify(require('image-size'))
const router = express.Router()
const upload = multer({
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads')
},
filename: (req, file, cb) => {
cb(null, file.originalname)
},
}),
})
router.post('/api/upload-banner', upload.single('banner'), async (req, res) => {
if (!req.file) {
return res.json({
success: false,
data: 'Image upload failed',
})
}
try {
const dimension = await imageSize(req.file.path)
if (dimension.width > 2000 || dimension.height > 2000) {
await unlink(req.file.path)
return res.json({
success: false,
data: 'Image file is too big',
})
}
} catch (error) {
return res.json({
success: false,
data: 'Internal server error',
})
}
return res.json({
success: true,
data: 'Image Uploaded Successfully',
})
})
module.exports = router
Here I have a post
API route that is using a middleware function from multer
package to process the uploaded image file. This middleware function will add information about the file in req.file
object.
Now I can access the path of that image file from req.file.path
and pass it to the imageSize()
function. It will return the width and height of the image file.
You can utilize this width and height information however you want. In this example, I am using this information for validation. If the width or height is greater than 2000, I will delete the file using unlink()
method and send an error response.
Get Image Width and Height from URLs
You can use the image-size
package to find image dimensions directly from a URL. This package can't handle URLs but we can download images using Node.js HTTPS module and pass the buffer to the imageSize()
function.
Because the imageSize()
function can process both an image path and buffer.
const url = require('url')
const https = require('https')
const imageSize = require('image-size')
const imgUrl = 'https://example.com/image.jpg'
const options = url.parse(imgUrl)
https.get(options, (response) => {
const chunks = []
response
.on('data', (chunk) => {
chunks.push(chunk)
})
.on('end', () => {
const buffer = Buffer.concat(chunks)
const dimension = imageSize(buffer)
console.log(dimension.width) // Image width
console.log(dimension.height) // Image height
})
})
The HTTPS module has a get()
method that accepts 2 arguments. The first argument is a URL object and the second argument is a callback function.
You can generate a URL object from your image URL by calling the url.parse()
method from the URL module in NodeJS. Inside the callback function, you will have the response.
Listen to the data event for getting the file buffer and storing them in an array. When data fetching completes, concatenate the array of buffers. Now you can call the imageSize()
function with this file buffer
to get the width and height values.
Also Read: How to Get All Files in Directories (Recursively) with Node.js
Conclusion
We have covered how to retrieve image dimensions using the image-size
package, which offers a simple and efficient solution that works with various image formats.
You saw different methods of using the package synchronously and asynchronously, as well as how to handle errors and optimize performance.
The ease of use of this package and support for various image formats make it a popular choice among Node.js developers. Overall, it is a reliable and efficient solution for getting image width and height in Node.js applications.