4

Is there a way to read transparent pixels from a picture using javascript?

I think, that it could be something similar to what PNG fixes does for IE (reading transparent pixels and applying some stuff, lol). But yes, for every browser..

Ah, would be awesome if it could be achieved without HTML5.

tomsseisums
  • 13,168
  • 19
  • 83
  • 145

3 Answers3

7

Well this question is actually answered by the dude from GoogleTechTalks in this video on javascript-based game engines. http://www.youtube.com/watch?feature=player_detailpage&v=_RRnyChxijA#t=1610s It should start at the point where it is explained.

Edit: So I will summarize what is told in the video and provide a code-example. It was a lot tougher than I had expected. The trick is to load your image onto a canvas and then check each pixel if it is transparent. The data is put into a two dimension array. Like alphaData[pixelRow][pixelCol]. A 0 is representing transparency while a 1 is not. When the alphaData array is completed it is put in global var a.

var a;
function alphaDataPNG(url, width, height) {

    var start = false;
    var context = null;
    var c = document.createElement("canvas");
    if(c.getContext) {
        context = c.getContext("2d");
        if(context.getImageData) {
            start = true;
        }
    }
    if(start) {
        var alphaData = [];
        var loadImage = new Image();
        loadImage.style.position = "absolute";
        loadImage.style.left = "-10000px";
        document.body.appendChild(loadImage);
        loadImage.onload = function() {
            c.width = width;
            c.height = height;
            c.style.width = width + "px";
            c.style.height = height + "px";
            context.drawImage(this, 0, 0, width, height);
            try {
                try {
                     var imgDat = context.getImageData(0, 0, width, height);
                } catch (e) {
                    netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
                    var imgDat = context.getImageData(0, 0, width, height);
                }                    
            } catch (e) {
                throw new Error("unable to access image data: " + e);
            }
            var imgData = imgDat.data;
            for(var i = 0, n = imgData.length; i < n; i += 4) {
                var row = Math.floor((i / 4) / width);
                var col = (i/4) - (row * width);
                if(!alphaData[row]) alphaData[row] = [];
                alphaData[row][col] = imgData[i+3] == 0 ? 0 : 1;
            }
            a=alphaData;
        };
        loadImage.src = url;
    } else {
        return false;
    }
}

I got errors when running local in Firefox and the try catch statement solved it. Oh I gotta eat...

Edit 2: So I finished my dinner, I'd like to add some sources I used and wich can be helpful.

https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas Info about the imageData object.

http://blog.nihilogic.dk/2008/05/compression-using-canvas-and-png.html Even more info about the imageData object and it's use.

http://www.nihilogic.dk/labs/canvascompress/pngdata.js A really helpful example of the use of imageData, the code I provided resembles this one for a big part.

http://www.youtube.com/watch?v=_RRnyChxijA Infos on scripting game-engines in javascript, really really interesting.

http://blog.project-sierra.de/archives/1577 Infos about the use of enablePrivilege in firefox.

Henderk
  • 159
  • 1
  • 3
  • 11
  • 1
    to make your answer even better, you could summarize the relevant part of the video ;-) – Benoit Garret Dec 07 '11 at 14:33
  • Wow, lot to think about. Thanks very much for your advice and the code. Someone somehow accepted the answer below, but I would have picked your answer. – Paeon Apr 01 '22 at 19:09
5

This is a bit tricky problem, since the only way to access files directly from Javascript is by using FileReader, which is a relatively new feature and not yet supported in most browsers.

However, you could get the desired result by using a canvas. If you have a canvas, you could assign it some distinctive color (such as neon green used in green screens). Then you could insert the image onto canvas and use the method mentioned here to get each individual pixel. Then you could check each pixel's color and see whether that point corresponds to your background color (ergo it's transparent) or does it have some other color (not transparent).

Kind of hackish, but don't think there's anything else you can do with pure JS.

Community
  • 1
  • 1
zatatatata
  • 4,761
  • 1
  • 20
  • 41
3

It appears that GameJS can do this and much, much more. I am referencing this SO question for any/all of my knowledge, as I don't claim to actually have any about this topic.

Of course, this is HTML5, and uses the canvas element.

Community
  • 1
  • 1
rockerest
  • 10,412
  • 3
  • 37
  • 67