Resizing & adding watermark on images with Nodejs and sharp-multer
Tags: javascript, node, tutorial, tooling
Published: 2022-09-05 10:03:03



## Motivation :
Whenever we start working with images upload Resizing comes firs and often we need to put watermark as well on last [post](https://dev.to/ranjan/simple-node-js-resize-image-before-upload-using-sharp-multer-p8c) we learned how to setup basic resizing and optimisation of the images with [sharp-multer](https://www.npmjs.com/package/sharp-multer). Here we are going to add advance Resizing and adding Watermark to all uploaded images.
 
## Prerequisites: 
Please Read [Part 1](https://dev.to/ranjan/simple-node-js-resize-image-before-upload-using-sharp-multer-p8c)  of the series here.

## Setup & Configuration :
on last part we have setup a simple NodeJS app with these files containing following code

### Server.js
```javascript
const express = require("express");
const path = require("path");
const multer = require("multer");
const SharpMulter = require("sharp-multer");
const app = express();

const storage = SharpMulter({
  destination: (req, file, callback) => callback(null, "images"),
  imageOptions: {
    fileFormat: "png",
    quality: 80,
    resize: { width: 500, height: 500 },
  }
});
const upload = multer({ storage });

app.post("/upload", upload.single("avatar"), async (req, res) => {
  console.log(req.file);
  return res.json("File Uploaded Successfully!");
});
app.get("/", function (req, res) {
  res.sendFile(path.join(__dirname, "/index.html"));
});

app.listen(3000, () => {
  console.log(`Server is running on port ${3000}`);
});
```

### index.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <title>File Upload</title>
</head>
<body>
    <div class="container">
        <h1>File Upload</h1>
<!--Create a form to send the file to a route  "upload"-->
<!--Set the request method to POST-->
<!--Set the encytype to "multipart/form-data" in order to send files and not just text-->
        <form action="/upload" method="POST" enctype="multipart/form-data">
            <div class="file-field input-field">
              <div class="btn grey">
                <input type="file" name="avatar">
              </div>
            </div>
            <button class="btn" type="submit">Submit</button>
          </form>
    </div>
</body>
</html>
```
we have our basic resizing and optimisation in place but now with `sharp-multer 0.2.1` we have few advance resizing options available to us we can now define what kind of resize mode to use for images 

### ResizeMode 
> resize.resizeMode

- `cover`: (default) Preserving aspect ratio, ensure the image covers both provided dimensions by cropping/clipping to fit.
- `contain`: Preserving aspect ratio, contain within both provided dimensions using "letterboxing" where necessary.
- `fill`: Ignore the aspect ratio of the input and stretch to both provided dimensions. _i.e images will be strached to match size provided_
- `inside`: Preserving aspect ratio, resize the image to be as large as possible while ensuring its dimensions are less than or equal to both those specified. _i.e width will be fixed to max value you provide and height will be adjusted to a lower value than provided according to Aspect Ratio_ .
- `outside`: Preserving aspect ratio, resize the image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified. _i.e height will be fixed to value you provide and width will be adjusted to a higher value than provided according to Aspect Ratio._

to use it we need to provide resizeMode key in imageOptions resize object ex :
```javascript

imageOptions: {
    fileFormat: "png",
    quality: 80,
    resize: { width: 500, height: 500, resizeMode: "outside" },
  }
```


## Add Watermark 

With new sharp-multer adding watermark is quite easy we can just provide the input image path and the place we want to put the watermark at.
 Currently we can put watermark at these location: `"center","top-left","top-right","bottom-left","bottom-right" ` and also the opacity of the watermark can be defined by passing opacity prop in the watermarkOptions so to add a watermark our storage configuration will look like this 

```javascript 
const storage = SharpMulter({
  destination: (req, file, callback) => callback(null, "images"),
  imageOptions: {
    fileFormat: "png",
    quality: 80,
    resize: { width: 500, height: 500, resizeMode: "outside" },
  },
  watermarkOptions: {
    input: "./images/logo.png", // watermark image location
    location: "top-right",
    opacity:50 // optional 
  },
});

```
you can find whole code in this [repo](https://github.com/ranjandsingh/image-upload-resize-test.git) try it out cheers.