如何在图像画布上计算该区域的transperent像素,我写了这个函数,但我想有类似于另一种方法
ctx = getCanvasImg();
for (var x = selection.x2 * zoom; x > selection.x1 * zoom; x--) {
for (var y = selection.y2 * zoom; y > selection.y1 * zoom; y--) {
var pixel = ctx.getImageData(x, y, 1, 1);
var data = pixel.data;
var rgba = 'rgba(' + data[0] + ',' + data[1] + ',' + data[2] + ',' + (data[3] / 255) + ')';
if (data[0] == 0) {
countWhite++;
}
}
}
答案 0 :(得分:5)
只需抓住需要的区域一次:
set /A
要计算所有不透明像素,您可以使用var idata = ctx.getImageData(startX, startY, widthOfArea, heightOfArea);
进行迭代:
Uint32Array
更新:只是为了澄清评论:这个做假设是小端CPU架构。现在大多数主流/消费类设备都使用这种CPU架构,这通常不是问题。但是,如果您怀疑您的代码会遇到大端系统,您必须提前检查并反转检查中的字节顺序(对于使用大于8位的类型数组视图的任何内容,因为它们将使用本机系统& #39; s架构)。
要检查系统上的字节顺序,您可以执行以下操作:
var data = new Uint32Array(idata.data.buffer);
// little-endian byte order
for(var i = 0, len = data.length, count = 0; i < len;) {
if (data[i++] >>> 24 === 255) count++; // shifts AABBGGRR to 000000AA, then =255?
}
// count = number of opaque pixels
如果是big-endian,请使用function isLittleEndian() {
return new Uint16Array(new Uint8Array([255,0]).buffer)[0] === 255
}
掩码而不是位移来检查这种方式:
and
您可以随时使用// big-endian byte order
for(var i = 0, len = data.length, count = 0; i < len;) {
if (data[i++] & 0xff === 255) count++; // masks RRGGBBAA to 000000AA, then =255?
}
并指定endianess,但是在这种情况下由于轻微的开销而没有任何好处。