画布仅获得不透明像素

Vit*_*ort 1 javascript html5 canvas

如何计算图像画布上区域的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++;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

只需抓住一次需要的区域:

var idata = ctx.getImageData(startX, startY, widthOfArea, heightOfArea);
Run Code Online (Sandbox Code Playgroud)

要计算所有不透明像素,可以使用a Uint32Array来迭代:

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
Run Code Online (Sandbox Code Playgroud)

更新:只是为了澄清评论:这确实假设了little-endian CPU架构.现在大多数主流/消费类设备都使用这种CPU架构,这通常不是问题.但是,如果您怀疑您的代码会遇到大端系统,您必须提前检查并反转检查中的字节顺序(对于使用大于8位的类型数组视图的任何内容,因为它们将使用本机系统建筑).

要检查系统上的字节顺序,您可以执行以下操作:

function isLittleEndian() {
  return new Uint16Array(new Uint8Array([255,0]).buffer)[0] === 255
}
Run Code Online (Sandbox Code Playgroud)

如果是big-endian,请使用and掩码而不是bit-shift 检查这种方式:

// 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?
}
Run Code Online (Sandbox Code Playgroud)

您总是可以使用DataViews并指定endianess,但是在这种情况下由于轻微的开销而没有任何好处.