tomsseisums
tomsseisums

Reputation: 13367

Read transparent pixels from image

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.

Upvotes: 4

Views: 5031

Answers (3)

Henderk
Henderk

Reputation: 159

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.

Upvotes: 7

zatatatata
zatatatata

Reputation: 4821

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.

Upvotes: 5

rockerest
rockerest

Reputation: 10508

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.

Upvotes: 3

Related Questions