DEV Community

Cover image for Resizing & adding watermark on images with Nodejs and sharp-multer
Ranjan Singh
Ranjan Singh

Posted on • Edited on

1 1

Resizing & adding watermark on images with Nodejs and sharp-multer

Motivation :

Whenever we start working with images upload Resizing comes firs and often we need to put watermark as well on last post we learned how to setup basic resizing and optimisation of the images with sharp-multer. Here we are going to add advance Resizing and adding Watermark to all uploaded images.

Prerequisites:

Please Read Part 1 of the series here.

Setup & Configuration :

on last part we have setup a simple NodeJS app with these files containing following code

Server.js

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}`);
});
Enter fullscreen mode Exit fullscreen mode

index.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>
Enter fullscreen mode Exit fullscreen mode

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 :


imageOptions: {
    fileFormat: "png",
    quality: 80,
    resize: { width: 500, height: 500, resizeMode: "outside" },
  }
Enter fullscreen mode Exit fullscreen mode

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

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 
  },
});

Enter fullscreen mode Exit fullscreen mode

you can find whole code in this repo try it out cheers.

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay