从图像中读取透明像素

发布于 2024-11-25 19:01:59 字数 142 浏览 1 评论 0原文

有没有办法使用javascript从图片中读取透明像素?

我认为,这可能类似于 PNG 修复对 IE 所做的事情(读取透明像素并应用一些东西,哈哈)。但是,是的,对于每个浏览器......

啊,如果不用 HTML5 也能实现,那就太棒了。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

栖竹 2024-12-02 19:01:59

这个问题实际上是由来自 GoogleTechTalks 的家伙在这个关于基于 javascript 的游戏引擎的视频中回答的。
http://www.youtube.com/watch?feature=player_detailpage& ;v=_RRnyChxijA#t=1610s
它应该从解释的地方开始。

编辑:
因此,我将总结视频中讲述的内容并提供一个代码示例。
这比我预想的要困难得多。诀窍是将图像加载到画布上,然后检查每个像素是否透明。数据被放入二维数组中。就像 alphaData[pixelRow][pixelCol] 一样。 0 表示透明度,而 1 则不表示。当 alphaData 数组完成后,它被放入全局变量 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;
    }
}

我在 Firefox 中本地运行时遇到错误,try catch 语句解决了这个问题。哦,我要吃东西......

编辑2:
所以我吃完了晚餐,我想添加一些我使用过的资源,这可能会有所帮助。

https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas
有关 imageData 对象的信息。

http://blog.nihilogic.dk/2008/05 /compression-using-canvas-and-png.html
有关 imageData 对象及其用途的更多信息。

http://www.nihilogic.dk/labs/canvascompress/pngdata.js
这是使用 imageData 的一个非常有用的示例,我提供的代码在很大程度上与此类似。

http://www.youtube.com/watch?v=_RRnyChxijA
有关用 javascript 编写游戏引擎脚本的信息,真的非常有趣。

http://blog.project-sierra.de/archives/1577
有关在 Firefox 中使用 enablePrivilege 的信息。

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.

娇纵 2024-12-02 19:01:59

这是一个有点棘手的问题,因为直接从 Javascript 访问文件的唯一方法是使用 FileReader,这是一个相对较新的功能,大多数浏览器尚不支持。

但是,您可以通过使用画布获得所需的结果。如果您有画布,您可以为其指定一些独特的颜色(例如绿色屏幕中使用的霓虹绿)。然后,您可以将图像插入到画布上,并使用此处提到的方法来获取每个单独的像素。然后您可以检查每个像素的颜色,看看该点是否对应于您的背景颜色(因此它是透明的)或者是否具有其他颜色(不透明)。

有点 hackish,但不要认为你可以用纯 JS 做任何其他事情。

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.

一个人的旅程 2024-12-02 19:01:59

看来 GameJS 可以做到这一点,甚至更多。我正在为任何/所有引用这个SO问题据我所知,因为我并不声称自己真正了解这个主题。

当然,这是 HTML5,并使用 canvas 元素。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文