如何从图像中获取像素的x,y坐标颜色?

时间:2012-01-05 22:49:32

标签: javascript html5 image-processing

有没有办法检查PNG图像的选定(x,y)点是否透明?

5 个答案:

答案 0 :(得分:181)

基于Jeff的回答,您的第一步是创建PNG的画布表示。下面创建一个离屏画布,其宽度和高度与图像相同,并在其上绘制图像。

var img = document.getElementById('my-image');
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);

之后,当用户点击时,使用event.offsetXevent.offsetY获取排名。然后可以使用它来获取像素:

var pixelData = canvas.getContext('2d').getImageData(event.offsetX, event.offsetY, 1, 1).data;

因为您只抓取一个像素,所以pixelData是一个包含像素的R,G,B和A值的四项数组。对于alpha,任何小于255的表示某种程度的透明度,0表示完全透明。

这是一个jsFiddle示例:http://jsfiddle.net/thirtydot/9SEMf/869/我在所有这些中使用jQuery是为了方便,但它绝不是必需的。

注意: getImageData属于浏览器的同源政策,以防止数据泄露,这意味着如果您使用来自其他域的图片弄脏画布或(我相信)此技术将失败,但有些浏览器可能已经解决了这个问题)来自任何领域的SVG。这可以防止站点为登录用户提供自定义图像资源并且攻击者想要读取图像以获取信息的情况。您可以通过从同一服务器提供映像或实现Cross-origin resource sharing来解决问题。

答案 1 :(得分:17)

Canvas将是一个很好的方法,正如@pst上面所说的那样。看看这个答案是个好例子:

getPixel from HTML Canvas?

一些专门为您提供服务的代码:

var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;

for (var i = 0, n = pix.length; i < n; i += 4) {
  console.log pix[i+3]
}

这将逐行进行,因此您需要将其转换为x,y并将for循环转换为直接检查或在内部运行条件。

再次阅读您的问题,看起来您希望能够获得此人点击的观点。使用jquery的click事件可以非常轻松地完成此操作。只需在点击处理程序中运行上面的代码:

$('el').click(function(e){
   console.log(e.clientX, e.clientY)
}

那些应该抓住你的x和y值。

答案 2 :(得分:2)

以 Brian Nickel 的回答为基础,仅将源图像的单个像素绘制到 1*1 像素的画布上,这比仅仅为了获得单个像素而绘制整个图像更有效:

function getPixel(img, x, y) {

    let canvas = document.createElement('canvas');
    canvas.width = 1;
    canvas.height = 1;
    canvas.getContext('2d').drawImage(img, x, y, 1, 1, 0, 0, 1, 1);;
    let pixelData = canvas.getContext('2d').getImageData(0, 0, 1, 1).data;

    return pixelData;   
}

答案 3 :(得分:1)

之前的两个答案演示了如何使用Canvas和ImageData。我想用runnable示例和使用图像处理框架提出答案,因此您不需要手动处理像素数据。

MarvinJ提供方法 image.getAlphaComponent(x,y),它只返回x,y坐标中像素的透明度值。如果此值为0,则像素是完全透明的,1到254之间的值是透明度级别,最后255是不透明的。

为了演示,我使用了下面的图像(300x300),透明背景和坐标(0,0)(150,150)的两个像素。

enter image description here

控制台输出:

(0,0):透明的 (150,150):NOT_TRANSPARENT

image = new MarvinImage();
image.load("https://i.imgur.com/eLZVbQG.png", imageLoaded);

function imageLoaded(){
  console.log("(0,0): "+(image.getAlphaComponent(0,0) > 0 ? "NOT_TRANSPARENT" : "TRANSPARENT"));
  console.log("(150,150): "+(image.getAlphaComponent(150,150) > 0 ? "NOT_TRANSPARENT" : "TRANSPARENT"));
}
<script src="https://www.marvinj.org/releases/marvinj-0.7.js"></script>

答案 4 :(得分:1)

使用:i << 2

const data = context.getImageData(x, y, width, height).data;
const pixels = [];

for (let i = 0, dx = 0; dx < data.length; i++, dx = i << 2) {
    if (data[dx+3] <= 8)
        console.log("transparent x= " + i);
}