Skip to content

Instantly share code, notes, and snippets.

@amnuts
Created January 12, 2016 15:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amnuts/d919e3951c6d911d3733 to your computer and use it in GitHub Desktop.
Save amnuts/d919e3951c6d911d3733 to your computer and use it in GitHub Desktop.
jquery plugin for toning an image
/**
* Usage:
*
* <img src="pic.jpg" data-colour="blue" />
* <img src="pic.jpg" data-colour="green" data-contrast="40" />
* <img src="pic.jpg" data-colour="pink" data-brightness="30" />
* <img src="pic.jpg" data-colour="#ddc258" data-contrast="40" data-brightness="30" />
* <script>$(function(){ $(img['data-colour']).toner(); });</script>
*/
;(function ($, window, document, undefined) {
var toner = 'toner',
defaults = {
colourMap: {
blue: '#1E428A',
lightblue: '#40B4E5',
flint: '#003035',
warmgrey: '#D6D2C4',
midgrey: '#94A596',
pink: '#EB6BB0',
red: '#DF465A',
orange: '#DC582A',
yellow: '#FFB81C',
green: '#00AFAA'
},
brightness: 20,
contrast: 40
};
function Plugin(element, options) {
this.element = element;
this.options = $.extend({}, defaults, options);
this.canvas = document.createElement('canvas');
this._defaults = defaults;
this._name = toner;
this.init();
};
Plugin.prototype.init = function() {
var colour = this.colour2rgb($(this.element).data('colour'));
if (colour == null) {
return;
}
this.canvas.width = this.element.width;
this.canvas.height = this.element.height;
this.canvas.getContext('2d').drawImage(this.element, 0, 0, this.element.width, this.element.height);
$(this.element).replaceWith(this.canvas);
this.greyscale();
this.brightness($(this.element).data('brightness'));
this.contrast($(this.element).data('contrast'));
this.multiply(colour);
};
/**
* Greyscale an image
*/
Plugin.prototype.greyscale = function() {
var context = this.canvas.getContext('2d');
var imageData = context.getImageData(0, 0, this.canvas.width, this.canvas.height),
data = imageData.data,
len = imageData.width * imageData.height * 4,
index = 0,
average;
while (index < len) {
average = (data[index] + data[index + 1] + data[index + 2]) / 3;
data[index] = average;
data[index + 1] = average;
data[index + 2] = average;
index += 4;
}
context.putImageData(imageData, 0, 0);
};
/**
* Colour the layer via multiply
*
* @param colour
*/
Plugin.prototype.multiply = function(colour) {
var context = this.canvas.getContext('2d'),
imageData = context.getImageData(0, 0, this.canvas.width, this.canvas.height),
data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
data[i] *= colour[0] / 255;
data[i + 1] *= colour[1] / 255;
data[i + 2] *= colour[2] / 255;
}
context.putImageData(imageData, 0, 0);
};
/**
* Adjust brightness
*
* @param brightness
*/
Plugin.prototype.brightness = function(brightness) {
brightness = brightness || this.options.brightness;
var context = this.canvas.getContext('2d'),
imageData = context.getImageData(0, 0, this.canvas.width, this.canvas.height),
data = imageData.data;
for (var i = 0, len = data.length; i < len; i += 4) {
data[i] += brightness;
data[i + 1] += brightness;
data[i + 2] += brightness;
}
context.putImageData(imageData, 0, 0);
};
/**
* Adjust contrast
*
* @param contrast
*/
Plugin.prototype.contrast = function(contrast) {
contrast = contrast || this.options.contrast;
var context = this.canvas.getContext('2d'),
imageData = context.getImageData(0, 0, this.canvas.width, this.canvas.height),
data = imageData.data;
var factor = (259 * (contrast + 255)) / (255 * (259 - contrast));
for (var i = 0, len = data.length; i < len; i += 4) {
data[i] = factor * (data[i] - 128) + 128;
data[i+1] = factor * (data[i+1] - 128) + 128;
data[i+2] = factor * (data[i+2] - 128) + 128;
}
context.putImageData(imageData, 0, 0);
};
/**
* Convert hex to rgba
*
* @param colour
* @returns {number[]}
*/
Plugin.prototype.colour2rgb = function(colour) {
if (Array.isArray(colour)) {
return colour;
}
if (this.options.colourMap.hasOwnProperty(colour)) {
colour = this.options.colourMap[colour];
}
if (colour.match(/^#?([0-9a-f]{6}|[0-9a-f]{3})$/i)) {
var value = colour.slice(colour.indexOf('#') + 1),
isShortNotation = (value.length === 3),
r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2),
g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4),
b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6);
return [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16), 1];
} else if (this.options.colourMap.hasOwnProperty(colour)) {
return this.options.colourMap[colour];
}
return null;
};
/**
* Prevent against multiple instantiations
*/
$.fn[toner] = function(options) {
return this.each(function () {
if (!$.data(this, 'plugin_' + toner)) {
$.data(this, 'plugin_' + toner, new Plugin(this, options));
}
});
};
})(jQuery, window, document);
@amnuts
Copy link
Author

amnuts commented Jan 12, 2016

This is just a straight-forward plugin to mono-tone images. A lot of the functionality is actually ripped from the excellent fabric.js.

It applies a bit of brightness and contrast adjustment before applying the colour, as this was required for my purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment