Implement HTML canvas image tinting function - javascript

First time StackOverflow poster here so please be gentle :)
I am trying to implement image tinting in HTML canvas for a game I'm developing. There were a lot of good suggestions here:
How do i tint an image with HTML5 Canvas?
And I successfully implemented one of those, but the image colours looked too washed out. I was impressed with the results here:
http://www.playmycode.com/blog/2011/06/realtime-image-tinting-on-html5-canvas/
And I tried to play with the code but it's simply not working in the fiddle I'm messing with (can't post a link to JS Fiddle as I don't have enough rep):
function generateRGBKs( img ) {
var w = img.width;
var h = img.height;
var rgbks = [];
var canvas = document.createElement("canvas");
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext("2d");
ctx.drawImage( img, 0, 0 );
var pixels = ctx.getImageData( 0, 0, w, h ).data;
// 4 is used to ask for 3 images: red, green, blue and
// black in that order.
for ( var rgbI = 0; rgbI < 4; rgbI++ ) {
var canvas = document.createElement("canvas");
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage( img, 0, 0 );
var to = ctx.getImageData( 0, 0, w, h );
var toData = to.data;
for (
var i = 0, len = pixels.length;
i < len;
i += 4
) {
toData[i ] = (rgbI === 0) ? pixels[i ] : 0;
toData[i+1] = (rgbI === 1) ? pixels[i+1] : 0;
toData[i+2] = (rgbI === 2) ? pixels[i+2] : 0;
toData[i+3] = pixels[i+3] ;
}
ctx.putImageData( to, 0, 0 );
// image is _slightly_ faster then canvas for this, so convert
var imgComp = new Image();
imgComp.src = canvas.toDataURL();
rgbks.push( imgComp );
}
return rgbks;
}
function generateTintImage( img, rgbks, red, green, blue ) {
var buff = document.createElement( "canvas" );
buff.width = img.width;
buff.height = img.height;
var ctx = buff.getContext("2d");
ctx.globalAlpha = 1;
ctx.globalCompositeOperation = 'copy';
ctx.drawImage( rgbks[3], 0, 0 );
ctx.globalCompositeOperation = 'lighter';
if ( red > 0 ) {
ctx.globalAlpha = red / 255.0;
ctx.drawImage( rgbks[0], 0, 0 );
}
if ( green > 0 ) {
ctx.globalAlpha = green / 255.0;
ctx.drawImage( rgbks[1], 0, 0 );
}
if ( blue > 0 ) {
ctx.globalAlpha = blue / 255.0;
ctx.drawImage( rgbks[2], 0, 0 );
}
return buff;
}
var img = new Image();
img.onload = function() {
var rgbks = generateRGBKs( img );
var tintImg = generateTintImage( img, rgbks, 200, 50, 100 );
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect( 0, 0, 100, 100 );
ctx.drawImage( tintImg, 50, 50 );
}
img.src = "https://pbs.twimg.com/profile_images/413816438701309953/uvZMK_gT_normal.jpeg";
I'm sure it's something stupid I've done and nothing wrong with Joe's code - can anyone help me get it working?
Many thanks :)

Because you're accessing the pixel data the image needs to be on the same domain as the code, or you can try using a base64 src.
img.src = "data:image/jpeg;base64,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";
You're breaking CORS policy
Heres a working JSFiddle

Related

PNG image with transparent background giving black background on canvas with drawImage and putImageData [duplicate]

My application stop working in Chrome 104, 105. Can anyone confirm this issue?
steps:
transparentDataArray: Uint8ClampedArray = new Uint8ClampedArray(w, h);
insert some values, leave 0,0,0,0 for transparent points
putImageData on context
drawImage over another context holding an image
=> expected (and working until 104) - replaces only non-transparent points
=> chrome 104 - replace transparent points with white color
const canvasMain = document.getElementById('main');
const contextMain = canvasMain.getContext('2d');
const canvas2 = document.createElement('canvas')
const context2 = canvas2.getContext('2d');
const drawData = () => {
console.log("draw data")
contextMain.putImageData(canvasDataInitial, 0, 0);
const dataArray = new Uint8ClampedArray(w * h * 4);
for (let i = 0; i < w * h; i = i + 4) {
dataArray[i] = 0;
dataArray[i + 1] = 150;
dataArray[i + 2] = 35;
dataArray[i + 3] = i > w * h / 3 ? 0 : 255;
}
canvas2.width = w;
canvas2.height = h;
context2.putImageData(new ImageData(dataArray, w, h), 0, 0);
contextMain.drawImage(canvas2, 0, 0);
}
let canvasDataInitial;
let w,h;
const image = new Image();
image.onload = () => {
w = image.width;
h = image.height;
contextMain.drawImage(image, 0, 0, w, h);
canvasDataInitial = contextMain.getImageData(0, 0, canvasMain.width, canvasMain.height);
drawData();
drawData();
setTimeout(drawData, 1000);
}
image.src = 'data:image/png;base64,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';
<!doctype html>
<html>
<body>
<canvas id="main" width="200" height="200" ></canvas>
</body>
</html>
The answer is "Yes, it's confirmed". The code snippet above proves Chrome behaves differently and oddly. Reported to chromium buglist.

Threshold image colors - Base64

I would like to use threshold filter on base64 string (data:image/png;base64,iVBOR...) using javaScript like this:
function threshold(base64) {
some action whith base64 string...
return base64; //base64 is updated by threshold filter
}
Is it possible and if it is, how can I do this?
var base64string = "data:image/png;base64,iVBOR..........",
threshold = 180, // 0..255
ctx = document.createElement("canvas").getContext("2d"),
image = new Image();
image.onload = function() {
var w = ctx.canvas.width = image.width,
h = ctx.canvas.height = image.height;
ctx.drawImage(image, 0, 0, w, h); // Set image to Canvas context
var d = ctx.getImageData(0, 0, w, h); // Get image Data from Canvas context
for (var i=0; i<d.data.length; i+=4) { // 4 is for RGBA channels
// R=G=B=R>T?255:0
d.data[i] = d.data[i+1] = d.data[i+2] = d.data[i+1] > threshold ? 255 : 0;
}
ctx.putImageData(d, 0, 0); // Apply threshold conversion
document.body.appendChild(ctx.canvas); // Show result
};
image.src = base64string;
MDN - putImageData
MDN - getImageData

On loading Image, getImageData delivers some zeros

I'm loading a PNG and try to check, whether it is fully opaque, meaning alpha channel is near 100% over the whole image. Therefore, I use the canvas and 2D-Context to get the pixel data and loop through it checking the alpha value.
To my surprise i get whole areas of zeros (RGBA = [0000]) where it obviously shouldn't.
Browser in focus: chrome 50.0.2661.87
Here is my code, it is embedded in a ThreeJS environment:
var imageData = zipHandler.zip.file(src); // binary image data
var texture = new THREE.Texture();
var img = new Image();
img.addEventListener( 'load', function ( event ) {
texture.imageHasTransparency = false; // extend THREEJS Texture by a flag
if (img.src.substring(imgSrc.length-4).toLowerCase().indexOf("png") > -1
|| img.src.substring(0, 15).toLowerCase().indexOf("image/png") > -1) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0, img.width, img.height );
var pixDataContainer = context.getImageData(0, 0, img.width, img.height);
var pixData = pixDataContainer.data;
// search for pixel.alpha < 250
for (var pix = 0, pixDataLen = pixData.length; pix < pixDataLen; pix += 4) {
if (pixData[pix+3] < 250) {
texture.imageHasTransparency = true;
break;
}
}
}
texture.image = img;
texture.needsUpdate = true;
this.removeEventListener('load', arguments.callee, false);
}, false );
var fileExtension = src.substr(src.lastIndexOf(".") + 1);
img.src = "data:image/"+fileExtension+";base64,"+ btoa(imageData.asBinary());
The order is correct: first define new Image(), then the onload function and then the source.
Solved. The image was larger than the canvas, so when context.drawImage() was started, only parts of the area was filled. I've set the canvas dimensions according to the image size, so now it works and we have
// ...
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = img.width; // !!!!!
canvas.height = img.height; // !!!!
context.drawImage(img, 0, 0, img.width, img.height );
var pixDataContainer = context.getImageData(0, 0, img.width, img.height);
var pixData = pixDataContainer.data;
// ...

remove white color of image javascript causes return of nothing

I used the following code to remove white color in image. It works for the image of the original fiddle, but it doesn't work with mine. I believe the code is totally fine, and it's a problem with the image I use, but why? And how can I make it work for my image?
Working with original image in tutorial: https://jsfiddle.net/gaby/UuCys/3/
NOT working with my image (I simply replace the img src): http://jsfiddle.net/UuCys/119/
Here is the code
When I try to return each pixel before changes, every pixel has 0 value for red,green or blue...why?
function white2transparent(img)
{
var c = document.createElement('canvas');
var w = img.width, h = img.height;
c.width = w;
c.height = h;
var ctx = c.getContext('2d');
ctx.drawImage(img, 0, 0, w, h);
var imageData = ctx.getImageData(0,0, w, h);
var pixel = imageData.data;
var r=0, g=1, b=2,a=3;
for (var p = 0; p<pixel.length; p+=4)
{
if (
pixel[p+r] == 255 &&
pixel[p+g] == 255 &&
pixel[p+b] == 255) // if white then change alpha to 0
{pixel[p+a] = 0;}
}
ctx.putImageData(imageData,0,0);
return c.toDataURL('image/png');
}

Opacity to canvas without affecting inner image

The problem I have is on the image slider. The blue triangule is created using a multiply canvas effect seen here:
http://albertogasparin.it/articles/2011/05/html5-multiply-filter-canvas/
I want the blue triangle to have it's opacity to 0.5, but if I put that on the css (canvas element) it also affects the opacity of the image that's below. Any ideas how to achieve this?
This is my code:
function to_canvas(im,w,h){
var isIE8 = $.browser.msie && +$.browser.version === 8;
var canvas;
var imageBottom;
var im_w = w;
var im_h = h;
var imgData;
var pix;
var pixcount = 0;
var paintrow = 0;
var multiplyColor = [70, 116, 145];
var x_offset = Math.floor(($('#'+im).attr('width') - im_w)/2);
var y_offset = Math.floor(($('#'+im).attr('height') - im_h)/2);
if ( isIE8 ) {
$('<div />' , {
'id' : 'div-'+im,
'class' : 'pseudo_canvas'
}).css({
'width' : im_w,
'height' : im_h
}).insertBefore('#'+im);
$('#'+im).appendTo('#div-'+im).fadeIn();
$('<img>' , {
'src' : '/img/blueborder.png',
'class' : 'blueborder'
}).css({
}).insertBefore('#'+im);
$('#'+im).appendTo('#div-'+im).fadeIn();
}else{
imageBottom = document.getElementById(im);
canvas = document.createElement('canvas');
canvas.width = im_w;
canvas.height = im_h;
imageBottom.parentNode.insertBefore(canvas, imageBottom);
ctx = canvas.getContext('2d');
ctx.drawImage(imageBottom, -x_offset , -y_offset);
imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
pix = imgData.data;
for (var i = 0 ; i < pix.length; i += 4) {
if(pixcount > im_w - (im_h - paintrow) ){
pix[i ] = multiply(multiplyColor[0], pix[i ]);
pix[i+1] = multiply(multiplyColor[1], pix[i+1]);
pix[i+2] = multiply(multiplyColor[2], pix[i+2]);
}
if(pixcount < im_w-1){
pixcount++;
}else{
paintrow++;
pixcount = 0;
}
}
ctx.putImageData(imgData, 0, 0);
/* $('#'+im).remove(); */
}
}
function multiply(topValue, bottomValue){
return topValue * bottomValue / 255;
}
This is how I want the triangle color/opacity (obviously without the opacity of the image on the back):
if u have canvas-
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.globalCompositeOperation = "destination-over";
context.fillStyle = "rgba(0, 0, 200, 0.5)";//Change the color combination here
context.fillRect(0, 0, 1000, 1000);
one way would be to use a semi-transparent background instead (e.g. png file)

Categories