Created
January 12, 2016 15:00
-
-
Save amnuts/d919e3951c6d911d3733 to your computer and use it in GitHub Desktop.
jquery plugin for toning an image
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.