AppDividend
Latest Code Tutorials

Node Express Image Upload and Resize Tutorial Example

2

Node Express Image Upload and Resize Tutorial Example is today’s topic. Node.js as a platform and express as a lightweight framework is the best choice for backend development. We can build Web APIs through this framework very quickly, and it has tremendous support for the NoSQL databases like MongoDB. You can find the tutorial about Node Express MongoDB tutorial on this blog. In this tutorial, we will upload an image to the Node.js server and resize the image using the sharp library.

Node Express Image Upload and Resize Tutorial

Okay, now let’s start our project.

Step 1: Create Node Express Project

Create a project folder by the following command.

mkdir nodeimageupload
cd nodeimageupload

Now, create a package.json file using the following command.

npm init -y

Next, install express as a framework,ejs as a template engine, body-parser, multer as a  node.js middleware for handling multipart/form-data, uuid for getting the random name, sharp as an image resize libraries using NPM.

npm install express body-parser ejs uuid multer sharp --save

Also, install the nodemon server as a development dependency.

npm install nodemon --save-dev

Now, open the project in Visual Studio Code.

Change the package.json file and add the following line in “scripts” object.

"scripts": {
    "start": "nodemon server.js"
},

Step 2: Create a server.js file.

Create one file in the project root called the server.js and added the following code inside it.

// server.js

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

app.listen(port, function () {
  console.log('Server is running on PORT',port);
});

Now, go to the terminal and start the node server by the following command.

npm start

 

Node Express Image Upload and Resize Tutorial Example

So, our nodemon development server is up and running.

Step 3: Configure the EJS templating engine.

For including the css and js files in the express, first, we will create a static directory called public in the root, and in that, we will put our CSS and JS files. So, create the first public directory.

Add the following code inside the server.js file.

// server.js

app.use(express.static('public'));

Next step is to set the ejs template engine. Add the following code inside the server.js file.

// server.js

app.set('view engine', 'ejs');

We need to create one folder inside our root called views. In that folder make one file called index.ejs.

<!-- index.ejs -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>EJS Engine</title>
  </head>
  <body>
    <p>Node Express Image Upload and Resize Example</p>
  </body>
</html>

Also, create an index.html file inside the public folder.

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=He, initial-scale=1.0">
   <meta http-equiv="X-UA-Compatible" content="ie=edge">
   <title>Node Express Image Upload Example</title>
</head>
<body>
   <p>
     Node Express Image Upload and Resize Example
   </p>
</body>
</html>

Step 4: Configure Express Router.

Set up the routes for our application. So use Router module provided by Express js. So, create a file in the root folder called router.js.

Now, write the following code inside the router.js file.

// router.js

const express = require('express');
const app = express();
const router = express.Router();

router.get('/', async function (req, res) {
  await res.render('index');
});
module.exports = router;

Now in the server.js filewe need to require the router.js file.

// server.js

const express = require('express');
const bodyParser = require('body-parser');

const app = express();
const port = process.env.PORT || 3000;
const router = require('./router');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.use(express.static('public'));
app.set('view engine', 'ejs');

app.use('/upload', router);

app.listen(port, function () {
  console.log('Server is running on PORT',port);
});

Now, go to the browser and hit this URL: http://localhost:3000/upload. You can see the basic HTML view.

Step 5: Create a form.

Inside the index.ejs file, we need to create one HTML form that can upload the image.

// index.ejs

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>EJS Engine</title>
  </head>
  <body>
      <p>Image Upload</p>
      <form method="post" action="upload/post" enctype="multipart/form-data">
        <input type="file" name="image" /><br /><br />
        <button type="submit" name="upload">Upload</button>
      </form>
  </body>
</html>

Now, go to the http://localhost:3000/upload and see the underlying HTML form that can upload an image.

Step 6: Create file upload middleware

Okay, to handle the multipart/form-data in Node.js, we have already installed the multer library. So let’s use that and create a middleware inside the root of the project called uploadMiddleware.js.

// uploadMiddleware.js

const multer = require('multer');

const upload = multer({
  limits: {
    fileSize: 4 * 1024 * 1024,
  }
});

module.exports = upload

Now, import this middleware inside the router.js file where we handle the POST request.

// router.js

const express = require('express');
const app = express();
const router = express.Router();
const upload = require('./uploadMiddleware');

router.get('/', async function (req, res) {
  await res.render('index');
});

router.post('/post', upload.single('image'), async function (req, res) {
  await console.log('post');
});

module.exports = router;

Here, we have used the node async await feature. 

So, when the user tries to upload an image, in the server, the router. Post function will be executed, and in the console, a post will be printed. That means, now we need to resize the image and then save in the file directory.

Step 7: Resize the image

For resizing the image in Node.js and achieve the High-performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images is Sharp. We have already installed the sharp. Now, create a file inside the root called Resize.js and add the following code.

// Resize.js

const sharp = require('sharp');
const uuidv4 = require('uuid/v4');
const path = require('path');

class Resize {
  constructor(folder) {
    this.folder = folder;
  }
  async save(buffer) {
    const filename = Resize.filename();
    const filepath = this.filepath(filename);

    await sharp(buffer)
      .resize(300, 300, {
        fit: sharp.fit.inside,
        withoutEnlargement: true
      })
      .toFile(filepath);
    
    return filename;
  }
  static filename() {
    return `${uuidv4()}.png`;
  }
  filepath(filename) {
    return path.resolve(`${this.folder}/${filename}`)
  }
}
module.exports = Resize;

So, in the above file, we have created a class called Resize.js and accepts one argument which is folder path up to images folder. Now, you need to create the images folder inside the public directory.

Then, we have defined the static function filename which returns the random string of filename and then define the filepath function which returns the complete filepath of that uploaded image.

Then we have defined the save() function, which accepts the file buffer coming from the user request and then resize that image and upload to that filepath and return the filename to the User.

Now, import the Resize.js file inside the router.js file.

Step 8: Save the image in the file system

Now, we need to import the Resize.js file inside the router.js file because we are handling the post request there. Write the following code inside the router.js file.

// router.js

const express = require('express');
const app = express();
const path = require('path');

const router = express.Router();
const upload = require('./uploadMiddleware');
const Resize = require('./Resize');

router.get('/', async function (req, res) {
  await res.render('index');
});

router.post('/post', upload.single('image'), async function (req, res) {
  const imagePath = path.join(__dirname, '/public/images');
  const fileUpload = new Resize(imagePath);
  if (!req.file) {
    res.status(401).json({error: 'Please provide an image'});
  }
  const filename = await fileUpload.save(req.file.buffer);
  return res.status(200).json({ name: filename });
});

module.exports = router;

First, inside the router.post request, we have defined the upload folder and then pass that folder to the constructor of Resize class. It will return the object and then we call the save() method on that object and pass the image buffer as an argument to the save() function and return the file name and we are for now just displaying the filename in JSON format to the User.

If the file is not there then we are displaying an error message to the user in JSON format.

Step 9: Run the Project.

Now, if you try to upload an image, you will see the output in the browser like below image.

 

Upload and Resize the image

So, we have got the correct JSON response. Now, go to the file system and inside the public >> images folder, you can see the randomly named image will be there.

Finally, Node Express Image Upload and Resize Tutorial Example is over. Thanks for taking and also, see the Github code, if you find any error.

Github Code

2 Comments
  1. Ulrich Bosbach says

    Dear Krunal,
    up to step 4 all things are working fine. After modifying server.js with the rooter path I get Error message “Cannot find module ‘./router’ “. In your description you write “So, create a file in the root folder called router.js. ” That might be wrong. Could you please correct it. The tutorial is good to understand. In this case I would apritiate to continue.
    Thanks in advance
    Ulrich

    1. Brody says

      Hey Ulrich, I think you’ve included an extra fullstop before your path declaration to the router module

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.