Типизированный массив javascript ImageData читает весь пиксель?

Итак, существует множество примеров того, как записать целый пиксель из представления Uint32Array объекта ImageData. Но можно ли считать пиксель целиком, не увеличивая счетчик в 4 раза? Из hacks.mozilla.org , запись пикселей rgba выглядит следующим образом: этим.

var imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);

var buf = new ArrayBuffer(imageData.data.length);
var buf8 = new Uint8ClampedArray(buf);
var data = new Uint32Array(buf);

for (var y = 0; y < canvasHeight; ++y) {
    for (var x = 0; x < canvasWidth; ++x) {
        var value = x * y & 0xff;

        data[y * canvasWidth + x] =
            (255   << 24) |    // alpha
            (value << 16) |    // blue
            (value <<  8) |    // green
             value;            // red
    }
}

imageData.data.set(buf8);

ctx.putImageData(imageData, 0, 0);

Но как я могу прочитать весь пиксель из одного смещения в 32-битном представлении ImageData? Вот что меня смущает, разве buf32 ниже не должно иметь длину 256/4 = 64?

// 8x8 image
var imgd = ctx.getImageData(0, 0, canvasWidth, canvasHeight),
    buf32 = new Uint32Array(imgd.data);

console.log(imgd.data.length);  // 256
console.log(buf32.length);      // 256  shouldn't this be 256/4 ?

Благодарность!


person leeoniya    schedule 21.05.2013    source источник


Ответы (2)


разобрался, мне нужно передать в конструктор Uint32Array сам буфер, а не другой BufferView.

var buf32 = new Uint32Array(imgd.data.buffer);
console.log(buf32.length)  // 64 yay!
person leeoniya    schedule 21.05.2013
comment
Спасибо, это было полезно и для меня! - person davidtbernal; 17.03.2014
comment
Это быстрее, чем перебирать пиксели? - person Captain Jack sparrow; 27.06.2016
comment
Спасибо, это именно то, что я искал. Перебор Uint32Array и сравнение значений (без создания хэшей) для моего приложения выполняется намного быстрее. - person Kirkman14; 23.10.2018
comment
Спасибо! сравнение двух способов итерации jsfiddle.net/cancerbero_sgx/05ve439a/13 - person cancerbero; 02.07.2019

длина буфера увеличена в четыре раза из-за ретина дисплея, надо писать pixelDensity(1); чтобы этого избежать

person 44 38    schedule 15.06.2019
comment
нет, это потому, что 8 бит используются для красного, другие 8 бит для зеленого и столько же для синего и альфа-канала. другими словами, каждый пиксель хранится в 8x4=32 битах. Если вы повторите uint8Array, у вас будет x4 элемента в массиве - person cancerbero; 02.07.2019