How to watermark an image with Node.js
Tags: jimp, javascript, node
Published: 2019-09-25 11:46:21

---
title: How to watermark an image with Node.js
published: true
description:
tags: jimp, javascript, nodejs
---

![](https://hashnode.imgix.net/res/hashnode/image/upload/v1569411659931/o29o1SXQQ.png?w=1600&h=840&fit=crop&crop=entropy&auto=format&q=60)

It's going to be a very simple tutorial.

First, let's create a node.js project

## Creating a Node.js project

```
mkdir jimp-watermark-demo
cd jimp-watermark-demo
```

```
npm init
```

Just press `Enter`, `Enter`, `Enter`...

```
npm install --save jimp
```

Open up your favorite editor. In my case it's Visual Studio Code. 
So I can just type

```
code .
```  

in terminal.

Create a file, name it `index.js`.


## Writing the code

Here's the working code. 

```javascript
const Jimp = require("jimp");

const ORIGINAL_IMAGE =
  "http://www.defence.gov.au/ADFA/Images/news_events/whiteRibbon.jpg";

const LOGO = "https://upload.wikimedia.org/wikipedia/en/thumb/9/9f/Australian_Defence_Force_Academy_coat_of_arms.svg/1200px-Australian_Defence_Force_Academy_coat_of_arms.svg.png";

const LOGO_MARGIN_PERCENTAGE = 5;

const FILENAME = "test.jpg";

const main = async () => {
  const [image, logo] = await Promise.all([
    Jimp.read(ORIGINAL_IMAGE),
    Jimp.read(LOGO)
  ]);

  logo.resize(image.bitmap.width / 10, Jimp.AUTO);

  const xMargin = (image.bitmap.width * LOGO_MARGIN_PERCENTAGE) / 100;
  const yMargin = (image.bitmap.width * LOGO_MARGIN_PERCENTAGE) / 100;

  const X = image.bitmap.width - logo.bitmap.width - xMargin;
  const Y = image.bitmap.height - logo.bitmap.height - yMargin;

  return image.composite(logo, X, Y, [
    {
      mode: Jimp.BLEND_SCREEN,
      opacitySource: 0.1,
      opacityDest: 1
    }
  ]);
};

main().then(image => image.write(FILENAME));
```

Now try to run 

```
node index.js
``` 

in your terminal.

It will create `test.jpg`. And that's the result.


## Okay, okay. Slow down. I don't get it. What does the code do?

```javascript
const Jimp = require("jimp");

const ORIGINAL_IMAGE =
  "http://www.defence.gov.au/ADFA/Images/news_events/whiteRibbon.jpg";

const LOGO = "https://upload.wikimedia.org/wikipedia/en/thumb/9/9f/Australian_Defence_Force_Academy_coat_of_arms.svg/1200px-Australian_Defence_Force_Academy_coat_of_arms.svg.png";

const LOGO_MARGIN_PERCENTAGE = 5;

const FILENAME = "test.jpg";
```

This part is pretty straight forward. We're importing `jimp` and defining some constants.

Next we're defining an async function `main`. We want it to be async because we want to do `async/await` inside the code. `async/await` can only work inside a function. 

```javascript
const [image, logo] = await Promise.all([
    Jimp.read(ORIGINAL_IMAGE),
    Jimp.read(LOGO)
  ]);
```

Here, we're reading an image from an url using `jimp`. `Jimp.read` result is a `Promise`. And we want to read these image in parallel. So, we use `Promise.all`. `Promise.all` also will produce `Promise`. So we use `await` to wait the result, and then we assign the result into `image`, and `logo`


```javascript
logo.resize(image.bitmap.width / 10, Jimp.AUTO);
```

We want to resize the logo size to be smaller. We want the logo width to be 10% of the image, and we just give `AUTO` for the height.

```javascript
const xMargin = (image.bitmap.width * LOGO_MARGIN_PERCENTAGE) / 100;
const yMargin = (image.bitmap.width * LOGO_MARGIN_PERCENTAGE) / 100;

const X = image.bitmap.width - logo.bitmap.width - xMargin;
const Y = image.bitmap.height - logo.bitmap.height - yMargin;
```

This is just the position of the logo. We want to position the logo on the bottom right. 

```javascript
return image.composite(logo, X, Y, [
    {
      mode: Jimp.BLEND_SCREEN,
      opacitySource: 0.1,
      opacityDest: 1
    }
  ]);
};
```

Here, we compose these two image together.

```javascript
main().then(image => image.write(FILENAME));
```

finally we write the result into `test.jpg`


That's it.
Hope it helps you :)