jar4563 Posted July 14, 2020 Share Posted July 14, 2020 Hi is it possible to access pixel data of single image in javascript? I have only found example of people using context.getImageData() to get the canvas pixel data but I need the image data so I can draw different color of images. is this possible? thx! Quote Link to comment Share on other sites More sharing options...
grelf Posted July 14, 2020 Share Posted July 14, 2020 (edited) Yes. context.getImageData() gets you an object with 3 properties: width, height and data. The last of these is an array of pixel data. 4 elements per pixel: red, green, blue and alpha. The last means transparency. You can read and write the elements of this array as you like and then context.putImageData() when complete (don't put after every change - performance would be awful). I usually add 2 methods to ImageData for pixel read/write: /* Returns an array with 4 elements: RGBA. */ ImageData.prototype.getPixel = function (x, y) { var i = (this.width * Math.round (y) + Math.round (x)) * 4; // NB: JavaScript will try to index arrays with non-integers! return [this.data [i], this.data [i + 1], this.data [i + 2], this.data [i + 3]]; }; /* rgba is an array with 4 elements: RGBA. Ignores transparent pixels (A = 0). */ ImageData.prototype.setPixel = function (x, y, rgba) { if (0 === rgba [3]) return; var i = (this.width * Math.round (y) + Math.round (x)) * 4; this.data [i] = rgba [0]; this.data [i + 1] = rgba [1]; this.data [i + 2] = rgba [2]; this.data [i + 3] = rgba [3]; }; Generally when I am wanting to do things on the canvas I do it in stages, some stages use standard context methods, other stages switch to pixel data as above. Keep the number of switches small. Edited July 14, 2020 by grelf Typos Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 14, 2020 Author Share Posted July 14, 2020 (edited) hey @grelf thx for the code but how do I apply this to the image? what I am trying to do is have a single .png file with flag shape in it and then change the color of that flag according to the team color Edit: And what I should have said is that I have done this type of thing before, many times. I just can't figure how to get access image's data Edited July 14, 2020 by jar4563 Quote Link to comment Share on other sites More sharing options...
grelf Posted July 14, 2020 Share Posted July 14, 2020 Load the image When it has loaded create an off-screen canvas of the same width and height Get the context of the canvas Draw the image into it getImageData() and use the methods I showed before to access the pixels jar4563 1 Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 14, 2020 Author Share Posted July 14, 2020 Just now, grelf said: When it has loaded create an off-screen canvas of the same width and height aah didn't know that was possible will try it, thx! Quote Link to comment Share on other sites More sharing options...
grelf Posted July 14, 2020 Share Posted July 14, 2020 var cnv = document.createElement ('canvas'); cnv.width = im.width; cnv.height = im.height; var g2 = cnv.getContext ('2d'); g2.drawImage (im, 0, 0); Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 14, 2020 Author Share Posted July 14, 2020 this is probably a stupid question but after done with the new canvas how to draw that to the main canvas? I probably have to keep in store all the canvas with changed flag colors? Quote Link to comment Share on other sites More sharing options...
grelf Posted July 14, 2020 Share Posted July 14, 2020 putImageData() into the main canvas using the ImageData object that you have been working with from the hidden canvas. The ImageData object, once obtained, is not tied to any particular canvas, it is just a collection of pixel data. Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 14, 2020 Author Share Posted July 14, 2020 ok thx. but will putImageData be slower to use when compared to the drawImage? Quote Link to comment Share on other sites More sharing options...
grelf Posted July 14, 2020 Share Posted July 14, 2020 No. In fact it may be faster (depending on browser implementation) because drawImage() is more flexible, capable of rescaling the image. jar4563 1 Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 14, 2020 Author Share Posted July 14, 2020 I have some weird error when I try to use getImageData() code: flag = new Image(); flag.src = "flag.png"; //flag.crossOrigin = "Anonymous"; testImageData = null; flag.addEventListener('load', function() { var canv = document.createElement("canvas"); canv.width = flag.width; canv.height = flag.height; var ctx = canv.getContext("2d"); ctx.drawImage (flag, 0, 0); console.log(">>> " + canv + " " + flag + " -- " + flag.width); testImageData = ctx.getImageData(0, 0, canv.width, canv.height); } , false); error: test.html:51 Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. at Image.<anonymous> Quote Link to comment Share on other sites More sharing options...
grelf Posted July 14, 2020 Share Posted July 14, 2020 I would create the onload function before setting flag.src, so the event handler is available before loading starts. I am not sure whether this will solve your problem but it might. Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 14, 2020 Author Share Posted July 14, 2020 (edited) 34 minutes ago, grelf said: I would create the onload function before setting flag.src, so the event handler is available before loading starts. I am not sure whether this will solve your problem but it might. nope did not. thx Edit: fortunately this was fixed by: --allow-file-access-from-files argument for chrome Edited July 14, 2020 by jar4563 fix Quote Link to comment Share on other sites More sharing options...
grelf Posted July 14, 2020 Share Posted July 14, 2020 Ah, yes that makes sense. I was just about to write that the "cross-origin" thing was a clue. I use Netbeans IDE (free) which has its own lightweight localhost server so I can run tricky things from local files without me having to set anything else up. Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 14, 2020 Author Share Posted July 14, 2020 (edited) @grelf nice. i just use notepad++ because it's light weight Edit: Nvm it was just the console.log that lagged Edited July 14, 2020 by jar4563 Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 14, 2020 Author Share Posted July 14, 2020 (edited) I am having issue with the transparency, the alpha = 0 turn into white even I'm skipping alpha = 0 pixels Edit: I think it's because the canvas is white by default. anyway to make it transparent? Edited July 14, 2020 by jar4563 Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 26, 2020 Author Share Posted July 26, 2020 (edited) Has anyone got the transparency working with putImageData ? It seems that even I put transparent pixels in the imagedata the putImageData ignores those and puts gray pixels or something to the canvas instead Edited July 26, 2020 by jar4563 Quote Link to comment Share on other sites More sharing options...
jar4563 Posted July 28, 2020 Author Share Posted July 28, 2020 (edited) nevermind. had some spaghetti code that didn't work. now it works and this is a valid method Edit: At least I assume we use the same method as I am using one with off screen canvas. and then that offscreen canvas is drawn using drawImage() Edited July 28, 2020 by jar4563 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.