Vito Motorsport
Vito Motorsport

Reputation: 73

Canvas get only opaque pixels

How to count transperent pixels of the area at image canvas, i wrote this function, but i guess there is something like a another method

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++;
        }
    }
}

Upvotes: 1

Views: 171

Answers (1)

user1693593
user1693593

Reputation:

Just grab the area in need once:

var idata = ctx.getImageData(startX, startY, widthOfArea, heightOfArea);

To count all opaque pixels, you can iterate using a Uint32Array instead:

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

Update: Just to clarify in regards to comments: this do assume little-endian CPU architecture. Most mainstream/consumer devices nowadays uses this CPU architecture and this is usually not a problem. However, if you suspect your code will come across big-endian systems you have to check for this in advance and reverse the byte-order in the check (for anything using typed arrays views wider than 8-bits as they will use the native systems's architecture).

To check for endianess on a system you can do this:

function isLittleEndian() {
  return new Uint16Array(new Uint8Array([255,0]).buffer)[0] === 255
}

And if big-endian, check this way instead using a and mask instead of 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?
}

You can always use DataViews and specify endianess, however in this case that is of no benefit due to the slight overhead.

Upvotes: 4

Related Questions