watermark.js

watermark(resources, [, options, [, promise]])

The watermark factory. Loads resources and returns an object with functions for manipulating them. resources can be a mixed array of any of the following: url, File, Blob, or Image. The options object is used to configure the watermark factory. For now it supports an init function that is used when loading images from a url, and is invoked with the image before fetching.

          
// load local images
watermark(['/img/coffee.jpg', '/img/logo.png']);

// load cross domain images
var options = {
  init: function (img) {
    img.crossOrigin = 'anonymous';
  }
};
watermark(['http://web.com/a.jpg', 'http://web.com/b.jpg'], options);

// load a url and a file object
var upload = document.querySelector('input[type=file]').files[0];
watermark(['/img/photo.jpg', upload]);
          
        

image(draw)

Converts all resources into an Image object by applying the function draw. The draw function receives all resources as canvases. Draw functions are expected to return the resource being watermarked.

          
// place a watermark in the upper left hand corner of an image
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .image(function (coffee, logo) {
    var context = coffee.getContext('2d');
    context.save();

    context.globalAlpha = alpha;
    context.drawImage(logo, 10, 10);

    context.restore();
    return target;
  });
          
        

blob(draw)

Converts all resources into a Blob object by applying the function draw. The draw function receives all resources as canvases. Draw functions are expected to return the resource being watermarked. Blob objects are useful for uploading generated watermarks.

          
// place a watermark in the upper left hand corner of an image
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .blob(function (coffee, logo) {
    var context = coffee.getContext('2d');
    context.save();

    context.globalAlpha = alpha;
    context.drawImage(logo, 10, 10);

    context.restore();
    return target;
  });
          
        

dataUrl(draw)

Converts all resources into a data url by applying the function draw. The draw function receives all resources as canvases. This function is used to create the base case for the image() and blob() functions.

          
// place a watermark in the upper left hand corner of an image
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .dataUrl(function (coffee, logo) {
    var context = coffee.getContext('2d');
    context.save();

    context.globalAlpha = alpha;
    context.drawImage(logo, 10, 10);

    context.restore();
    return target;
  });
          
        

then(fn)

Delegates to the Promise that was passed to the watermark() factory. This function is used to do something with the result of watermarking.

          
// append a generated image
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .image(watermark.image.lowerRight(0.5))
  .then(function (img) {
    document.getElementById('preview').appendChild(img);
  });

// upload a watermarked image
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .blob(watermark.text.lowerRight('watermark.js', '48px serif', '#fff', 0.5))
  .then(function (blob) {
    // perform upload using FormData
  });

// use a data url as an image source
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .dataUrl(watermark.image.lowerLeft(0.5))
  .then(function (url) {
    document.querySelector('img').src = url;
  });
          
        

load(resources, [init])

Load additional resources. resources and init behave just as they do in the watermark() factory. This function is useful for loading images on top of already generated watermarks.

          
// one watermark in the lower right and one in the upper left
watermark(['/img/boat.jpg', '/img/logo.png'])
  .image(watermark.image.lowerRight(0.5))
  .load(['/img/other-logo.png'])
  .image(watermark.image.upperLeft(0.5))
  .then(function (img) {
    document.getElementById('#preview').appendChild(img);
  });
          
        

render()

Apply all transformations to the watermarked image and load it as a resource. Useful for general post-processing or writing additional text on a watermarked image.

          
// write multiple text watermarks
var text = watermark.text
watermark(['/img/shepherd.jpg'])
  .image(text.lowerRight('watermark.js', '48px Josefin Slab', '#fff', 0.5))
  .render()
  .image(text.upperLeft('watermark.js', '48px Josefin Slab', '#fff', 0.5, 48))
  .then(function (img) {
    document.getElementById('#preview').appendChild(img);
  });
          
        

destroy()

watermark.js makes use of a canvas pool to reuse resources as much as possible. This is accomplished with a shared pool. The destroy() function on the watermark() factory explicitly destroys all remaining canvas references in the pool and should be used to clean up after doing a bunch of watermark operations.

          
// remove any remaining canvas references
watermark.destroy();
          
        

Styles

As noted about draw functions, they accept canvas objects and perform various operations on them to compose a single image. watermark.js comes with two namespaces featuring common draw operations for watermarks.

watermark.image

This namespace contains functions for positioning watermark images and controlling opacity. Most of these functions accept an alpha value and return a positioning function.

          
// draw the logo at the lower right corner at 50% opacity
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .image(watermark.image.lowerRight(0.5));

// draw the logo at the lower left corner at 50% opacity
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .image(watermark.image.lowerLeft(0.5));

// draw the logo at the upper right corner at 50% opacity
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .image(watermark.image.upperRight(0.5));

// draw the logo at the upper left corner at 50% opacity
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .image(watermark.image.upperLeft(0.5));

// draw the logo at the center at 50% opacity
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .image(watermark.image.center(0.5));

/**
 * Callback for determining the x coordinate of the watermark
 *
 * @param {HTMLCanvasElement} coffee
 * @param {HTMLCanvasElement} logo
 * @return {Number}
 */
var getX = function(coffee, logo) {
  return 73;
};

/**
 * Callback for determining the y coordinate of the watermark
 *
 * @param {HTMLCanvasElement} coffee
 * @param {HTMLCanvasElement} logo
 * @return {Number}
 */
var getY = function(coffee, logo) {
  return 63;
};

// draw the logo at an arbitrary location at 60% opacity
watermark(['/img/coffee.jpg', '/img/logo.png'])
  .image(watermark.image.atPos(getX, getY, 0.6));
          
        

watermark.text

This namespace contains functions for positioning watermark text and controlling opacity. Most of these functions accept font styles and an alpha value and return a positioning function.

          
// draw 48px white text at the lower right corner at 50% opacity
watermark(['/img/coffee.jpg'])
  .image(watermark.text.lowerRight('watermark.js', '48px sans-serif', '#fff', 0.5));

// draw 48px white text at the lower left corner at 50% opacity
watermark(['/img/coffee.jpg'])
  .image(watermark.text.lowerLeft('watermark.js', '48px sans-serif', '#fff', 0.5));

/**
 * Note: functions for drawing to the upper right and left corners
 * support an additional y parameter due to browser limitations of
 * the TextMetrics object used to calculate font height. When in doubt
 * just use the size of your font for this parameter.
 */

// draw 48px white text at the upper right corner at 50% opacity
watermark(['/img/coffee.jpg'])
  .image(watermark.text.upperRight('watermark.js', '48px sans-serif', '#fff', 0.5, 48));

// draw 48px white text at the upper left corner at 50% opacity
watermark(['/img/coffee.jpg'])
  .image(watermark.text.upperLeft('watermark.js', '48px sans-serif', '#fff', 0.5, 48));

// draw 48px white text at the center at 50% opacity
watermark(['/img/coffee.jpg'])
  .image(watermark.text.center('watermark.js', '48px sans-serif', '#fff', 0.5));

/**
 * Callback for determining the x coordinate of the watermark
 *
 * @param {HTMLCanvasElement} coffee
 * @param {TextMetrics} metrics
 * @param {CanvasRenderingContex2D} context - context of the coffee canvas
 * @return {Number}
 */
var x = function(coffee, metrics, context) {
  return 73;
};

/**
 * Callback for determining the y coordinate of the watermark
 *
 * @param {HTMLCanvasElement} coffee
 * @param {TextMetrics} metrics
 * @param {CanvasRenderingContex2D} context - context of the coffee canvas
 * @return {Number}
 */
var y = function(coffee, metrics, context) {
  return 63;
};

// draw 48px white text at an arbitrary location at 60% opacity
watermark(['/img/coffee.jpg'])
  .image(watermark.text.atPos(x, y, 'watermark.js', '48px sans-serif', '#fff', 0.6));
          
        

Custom Styles

Creating your own custom styles is easy. Since watermark.js subscribes to the functional style, a good pattern is to write functions that return functions.

  
watermark(['/img/coffee.jpg'])
  image(myRadRotateFunction(0.5));
  

Keep in mind that these draw functions receive canvas objects, so in order to keep them composable it is a good idea to leave the context the way you found it.

  
function myRadRotateFunction(alpha) {
  return function(target) {
    var context = target.getContext('2d');
    context.save(); // capture the state of the context

    // do some cool rotating things

    context.restore(); // put the context back where you found it
    return target;
  }
}
  

Note that we return the target canvas after we are done. This is required in order for watermark.js to pass the finished product to then when you are ready to do something with your watermarked image.