有没有办法检查PNG图像的选定(x,y)点是否透明?
如何检查图像的特定像素是否透明?
基于 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.offsetX
和event.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 弄脏了画布,则此技术将失败。这可以防止站点为登录用户提供自定义图像资产并且攻击者想要读取图像以获取信息的情况。您可以通过从同一服务器提供图像或实施跨域资源共享来解决问题。
正如上面@pst 所说,画布将是一个很好的方法来做到这一点。查看此答案以获取一个很好的示例:
一些可以专门为您服务的代码:
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 的点击事件轻松完成。只需在单击处理程序中运行上面的代码,如下所示:
$('el').click(function(e){
console.log(e.clientX, e.clientY)
}
那些应该抓住你的 x 和 y 值。
前两个答案演示了如何使用 Canvas 和 ImageData。我想提出一个带有可运行示例并使用图像处理框架的答案,因此您无需手动处理像素数据。
MarvinJ提供了image.getAlphaComponent(x,y)方法,它简单地返回 x,y 坐标中像素的透明度值。如果这个值为 0,像素是完全透明的,1 到 254 之间的值是透明度级别,最后 255 是不透明的。
为了演示,我使用了下面的图像 (300x300) 透明背景和坐标(0,0)和(150,150)处的两个像素。
控制台输出:
(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>
以 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;
}
和 : 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);
}