Просто захватить область в необходимости раз:
var idata = ctx.getImageData(startX, startY, widthOfArea, heightOfArea);
подсчитать все непрозрачные пиксели, вы можете перемещаться с помощью 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
Обновление: просто уточнить в отношении комментариев: это do Предположим, что архитектура с минимальным уровнем детализации. Большинство основных/потребительских устройств в настоящее время используют эту архитектуру процессора, и это обычно не проблема. Однако, если вы подозреваете, что ваш код столкнется с системами на базе большого числа, вы должны заранее проверить это и отменить порядок байтов в проверке (для чего-либо, используя типизированные массивы, более 8 бит, поскольку они будут использовать собственные системы архитектура).
Чтобы проверить порядок байтов в системе вы можете сделать это:
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?
}
Вы всегда можете использовать DataView
s и указать endianess, однако в этом случае это не принесет пользы из-за небольших накладных расходов.
Что-то не в порядке с решением проблемы? –