Reputation: 35
I am using this js: http://www.jqueryscript.net/other/jQuery-Image-Processing-Plugin-With-Canvas-Tancolor.html
What this plugin is doing, it is converting my canvas to black and white and saving it in an IMG tag on my web page.
Here is the javascript this plugin is using:
(function ($) {
$.fn.tancolor = function(options) {
var settings = $.extend({
mode: 'grayscale',
r_weight: 0.34,
g_weight: 0.5,
b_weight: 0.16,
r_intensity: 1,
g_intensity: 1,
b_intensity: 1,
load: null
}, options );
var r_weight;
var g_weight;
var b_weight;
var r_intensity;
var g_intensity;
var b_intensity;
// settings value
switch(settings.mode){
case 'grayscale':
r_weight = 0.34;
g_weight = 0.5;
b_weight = 0.16;
r_intensity = 1;
g_intensity = 1;
b_intensity = 1;
break;
case 'red':
r_weight = 0.34;
g_weight = 0.5;
b_weight = 0.16;
r_intensity = 255;
g_intensity = 1;
b_intensity = 1;
break;
case 'green':
r_weight = 0.34;
g_weight = 0.5;
b_weight = 0.16;
r_intensity = 1;
g_intensity = 255;
b_intensity = 1;
break;
case 'blue':
r_weight = 0.34;
g_weight = 0.5;
b_weight = 0.16;
r_intensity = 1;
g_intensity = 1;
b_intensity = 255;
break;
default:
r_weight = settings.r_weight;
g_weight = settings.g_weight;
b_weight = settings.b_weight;
r_intensity = settings.r_intensity;
g_intensity = settings.g_intensity;
b_intensity = settings.b_intensity;
break;
}
// convert image to canvas
var img = document.getElementById($(this).attr("id"));
if(settings.load){
img.src = settings.load;
return;
}
var canvas = convertImageToCanvas(img);
var ctx = canvas.getContext("2d");
var imageData = ctx.getImageData(0, 0, img.width, img.height)
$(this).replaceWith(canvas);
// Processing image data
var data = imageData.data;
for(var i = 0; i < data.length; i += 4) {
var brightness = r_weight * data[i] + g_weight * data[i + 1] + b_weight * data[i + 2];
// red
data[i] = r_intensity * brightness;
// green
data[i + 1] = g_intensity * brightness;
// blue
data[i + 2] = b_intensity * brightness;
}
ctx.putImageData(imageData, 0, 0);
$('#'+$(this).attr("id")).each(function(i,e){
var img = e.toDataURL("image/png");
$(e).replaceWith( $('<img src="' + img + '"/>').attr({width: $(e).attr("width"), height: $(e).attr("height"), style: $(e).attr("style") }) ) });
// Converts image to canvas; returns new canvas element
function convertImageToCanvas(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
if(image.id) {
canvas.id = image.id;
}
if(image.className) {
canvas.className = image.className;
}
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
}
// Converts canvas to an image
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
};
}(jQuery));
What I actually want is just convert my canvas to black and white but saving it in canvas tag only on web page and not as IMG tag as I am than after downloading the greyscale canvas merging with another canvas from the app.
Any help will be appreciated.
Thanks
Upvotes: 1
Views: 4358
Reputation: 136707
To grayscale a non-transparent image, on compatible browsers, you could simply [if Safari didn't had a strange bug with that, you should have been able to] use the context.globalCompositeOperation
property and set it to 'luminosity'
after you've drawn a solid color, before falling to the getImageData
solution :
var img = new Image();
var ctx = canvas.getContext('2d');
img.onload = function() {
// set the canvas' size
canvas.width = this.width;
canvas.height = this.height;
// first fill a rect
ctx.fillStyle = 'white'
ctx.fillRect(0, 0, canvas.width, canvas.height);
// set the gCO
ctx.globalCompositeOperation = 'luminosity';
// if the browser doesn't support Blend Modes
console.log(ctx.globalCompositeOperation)
if (ctx.globalCompositeOperation !== 'luminosity')
fallback(this);
else {
// draw the image
ctx.drawImage(this, 0, 0);
// reset the gCO
ctx.globalCompositeOperation = 'source-over';
}
}
img.crossOrigin = "anonymous";
img.src = "https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png";
function fallback(img) {
// first remove our black rectangle
ctx.clearRect(0, 0, canvas.width, canvas.height);
//draw the image
ctx.drawImage(img, 0, 0);
// get the image data
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var d = imgData.data;
// loop through all pixels
// each pixel is decomposed in its 4 rgba values
for (var i = 0; i < d.length; i += 4) {
// get the medium of the 3 first values
var med = (d[i] + d[i + 1] + d[i + 2]) / 3;
// set it to each value
d[i] = d[i + 1] = d[i + 2] = med;
}
// redraw the new computed image
ctx.putImageData(imgData, 0, 0);
}
<canvas id="canvas"></canvas>
But since Safari has a bug and that the gCO solution (which is faster, but I don't think it's important for you) remove the transparent pixels, here is just the previous fallback, which is a simpler code than the one you got. I hope you'll be able to read it.
var img = new Image();
var ctx = canvas.getContext('2d');
img.onload = function() {
// set the canvas' size
canvas.width = this.width;
canvas.height = this.height;
//draw the image
ctx.drawImage(this, 0, 0);
// get the image data
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var d = imgData.data;
// loop through all pixels
// each pixel is decomposed in its 4 rgba values
for (var i = 0; i < d.length; i += 4) {
// get the medium of the 3 first values ( (r+g+b)/3 )
var med = (d[i] + d[i + 1] + d[i + 2]) / 3;
// set it to each value (r = g = b = med)
d[i] = d[i + 1] = d[i + 2] = med;
// we don't touch the alpha
}
// redraw the new computed image
ctx.putImageData(imgData, 0, 0);
}
img.crossOrigin = "anonymous";
img.src = "https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png";
<canvas id="canvas"></canvas>
Upvotes: 2