DEV Community

Cover image for Create Image Watermark using Nodejs
Nguyễn Thanh Hòa
Nguyễn Thanh Hòa

Posted on

Create Image Watermark using Nodejs

Today, I share simple example "Create Imate Watermark using Nodejs"

We research "jimp" library. jimp have write using javascript support in Nodejs
with following types of support
@ jimp / jpeg
@ jimp / png
@ jimp / bmp
@ jimp / tiff
@ jimp / gif
You can learn more here: https://www.npmjs.com/package/jimp
Okay, we can install it, following below code

npm install --save jimp
Enter fullscreen mode Exit fullscreen mode

After when install succesfully, you can setup code it , following bellow code
Create watermate.js file in directory, after then following bellow code copy

const Jimp = require("jimp");

const ORIGINAL_IMAGE =__dirname+"/images/create-project-laravel5_8-using-composer-01.jpg";

const LOGO = __dirname+"/images/logo.png";

//save image name
const FILENAME = "create-project-laravel5_8-using-composer-01.jpg"; 

const main = async (a) => {

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

  logo.resize(logo.bitmap.width , Jimp.AUTO);

  const X=10; 
  const Y=10;

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

main(ORIGINAL_IMAGE).then(image => image.write(FILENAME));
Enter fullscreen mode Exit fullscreen mode

The above code, you see we config coordinates (x,y) position add image logo

You can run project : node watermart.js
You will see the image saved in the project, please open it to preview.
In this article, I show you how to create watermark on images, you can combine with the article Crawl Data Website Using Nodejs to be able to both download images and watermark them all at once!

Full Code Crawl Data Webiste and Image Watermart

//file: index.js
const rp = require("request-promise");
const cheerio = require("cheerio");
const request = require('request');
const url = require('url')
const https = require('https')
const sizeOf = require('image-size')
const fs = require("fs");
const dslink = "dslink.txt";
const domain = "https://hoanguyenit.com";
const img_width=500;
const img_heigth=250;

///watemat
const Jimp = require("jimp");
const LOGO = __dirname+"/images/logo.png";
const main = async (a) => {
    //  console.log( a);
    const [image, logo] = await Promise.all([
      Jimp.read(a),
      Jimp.read(LOGO)
    ]);

    logo.resize(logo.bitmap.width , Jimp.AUTO);
   // const X=30;
   // const Y=image.bitmap.height - logo.bitmap.height;
    //console.log(X +"/"+Y);
    const X=10;
    const Y=10;

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



var array = fs.readFileSync(dslink).toString().split("\n");
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
function removeItemAll(arr, value) {
    var i = 0;
    while (i < arr.length) {
        if (arr[i] === value) {
            arr.splice(i, 1);
        } else {
            ++i;
        }
    }
    return arr;
}
async function crawler() {
    await sleep(1000);
    for (i in array) {
        const linkchay = array[i];

        try {
            const options = {
                uri: linkchay,
                transform: function (body) {
                    //Khi lấy dữ liệu từ trang thành công nó sẽ tự động parse DOM
                    return cheerio.load(body);
                },
            };
            var $ = await rp(options);
        } catch (error) {
            console.log("Link dang dung:" + array[i]);
            return error;
        }

        /* Lấy tên và miêu tả của tutorial*/
        const title = $(".ten_title").text().trim();
        //const description = $(".entry-content > p").text().trim();

        /* Phân tích các table và sau đó lấy các posts.
           Mỗi table là một chương 
        */
        const tableContent = $(".info_content");
        let data = [];
        // Tên của chương đó.
        let chaperTitle = tableContent.find("p").text().trim();


        //Tìm bài viết ở mỗi chương
        let namefile = "";
        let chaperData = []
        const chaperLink = tableContent.find("p").find("img");

        for (let j = 0; j < chaperLink.length; j++) {
            const post = $(chaperLink[j]);
            const postLink = post.attr("src");
            //download
            const n = postLink.lastIndexOf("/");
            const filename = postLink.substring(n + 1, postLink.length);
            namefile = filename;
            download(postLink, filename, function () {
                //console.log("Link:"+linkchay);
            });
            const postTitle = post.text().trim();
            chaperData.push({
                postTitle,
                linkchay,
                filename,
            });
        }
        data.push({
            chaperTitle,
            chaperData,

        });


        // Lưu dữ liệu về máy
        fs.writeFileSync('data.json', JSON.stringify(data))
        console.log(linkchay + "------------->done");
        removeItemAll(array, linkchay);
        await sleep(1000);
    }


};

crawler();

async function getFilesizeInBytes(filename) {
    const stats = fs.statSync(filename);
    const fileSizeInBytes = stats.size;
    return fileSizeInBytes;
}

var download = function (uri, filename, callback) {
    var link = "";
    if (uri.search("https") == -1) {
        link = domain + "/" + uri;
    } else {
        link = uri;
    }

    const imgUrl = link;
    const options = url.parse(imgUrl);
    https.get(options, function (response) {
        const chunks = []
        response.on('data', function (chunk) {
          chunks.push(chunk)
        }).on('end', function() {
          const buffer = Buffer.concat(chunks)
          let width = sizeOf(buffer).width;
          let height = sizeOf(buffer).height;
          //check size image mà ta muốn lấy
          if(width>200 && height>200){
            request.head(link, function (err, res, body) {
                if(res.statusCode==200){
                    request(link).pipe(fs.createWriteStream('./images/' + filename)).on('close', callback);
                    setTimeout(function(){
                        main(__dirname+"/images/"+filename).then(image => image.write(__dirname+"/luu/"+filename));
                    },2000);

                }

            });
          }
        })
    })


};

Enter fullscreen mode Exit fullscreen mode

The above code is that I combine 2 articles together to both download images and watermark for images
The article:

Discussion (1)

Collapse
ra1nbow1 profile image
Matvey Romanov

That’s pretty useful