Search code examples
javascriptimagecanvaswatermarkimage-compression

Use image as watermark with compressor.js


I am using compressor.js for image compression and watermarking. However, only text based watermark seems to be possible to me. I want to add image (logo) into watermark too.

Any idea how to use image as watermark with compressor.js?


Solution

  • You can do this by using the drew function, like so:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <script src="https://cdnjs.cloudflare.com/ajax/libs/compressorjs/1.0.7/compressor.min.js"></script>
    </head>
    <body>
      <img id="watermark" src="watermark.png" style="display: none" />
      <h3>Input</h3>
      <div id="input"><img id="image" src="picture.png" style="max-width:250px"></div>
      <h3>Output</h3>
      <div id="output"></div>
      <script>
        window.addEventListener('DOMContentLoaded', function () {
          var Compressor = window.Compressor;
          var URL = window.URL || window.webkitURL;
          var image = document.getElementById('image');   
          var output = document.getElementById('output');
          var watermark = document.getElementById('watermark');
          var xhr = new XMLHttpRequest();
    
          xhr.onload = function () {
            new Compressor(xhr.response, {
              strict: false,
              drew: function (context, canvas) {
                context.drawImage(
                  watermark,
                  0,
                  0,
                  watermark.width,
                  watermark.height,
                  canvas.width - ((watermark.width / 4) + 10),
                  canvas.height - ((watermark.height / 4) + 10),
                  (watermark.width / 4),
                  (watermark.height / 4))
              },
              success: function (result) {
                var newImage = new Image();
                newImage.src = URL.createObjectURL(result);
                newImage.style = "max-width:250px";
                output.appendChild(newImage);
              },
              error: function (err) {
                window.alert(err.message);
              },
            });
          };
    
          xhr.open('GET', image.src);
          xhr.responseType = 'blob';
          xhr.send();
        });
      </script>
    </body>
    </html>
    

    All of the dividing by 4 is because my watermark image is massive. That's not required.

    Here's a screenshot of the before/after:

    Before + After

    Alternative Method

    Here's an alternative way to add a watermark to an image:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
    </head>
    <body>
      <img id="watermark" src="https://upload.wikimedia.org/wikipedia/en/7/71/Corona_Extra.svg" style="display: none" />
      <img id="image" src="https://images.unsplash.com/photo-1665606855702-144fd49af552?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80%20870w" style="display:none">
      <canvas id="output"></canvas>
      <script>
      
        var imagesLoaded = 0;
        var main = document.getElementById("image");
        var watermark = document.getElementById("watermark");
        
        function imageHasLoaded() {
            imagesLoaded++;
            if (imagesLoaded == 2) {
                var c = document.getElementById("output");
                var ctx = c.getContext("2d");
                
                c.width = main.width;
                c.height = main.height;
                ctx.drawImage(main,
                              0, 0,
                              main.width, main.height,
                              0, 0,
                              main.width, main.height);
                ctx.drawImage(watermark,
                              0, 0,
                              watermark.width, watermark.height,
                              (main.width - watermark.width) / 2, (main.height - watermark.height),
                              watermark.width, watermark.height);
            }
        }
        
        main.load = imageHasLoaded();
        watermark.load = imageHasLoaded();
        
      </script>
    </body>
    </html>