Вмъкване на множество пиксели с данни за изображение на платно

Извличам пиксели в данни за изображение на платно и го правя често.

Мисля, че вмъкването и извличането от и към изображението на платното е скъпо като процесорно време, така че искам да направя възможно най-малко от тях.

Един от начините за рязане би бил да се направи единична вложка, която да вмъкне множество пиксели в една последователност, но досега не съм успял да видя как ще стане това. Всички примери, които съм виждал досега, извличат и вмъкват само един пиксел.

Така че въпросът е, за да се ускори манипулирането на пикселите с данни за изображението на платното, как да вмъкна/извлека няколко пиксела едновременно?


person john-jones    schedule 05.11.2014    source източник


Отговори (1)


Просто изберете по-голям регион, когато извличате пикселен буфер:

var imageData = ctx.getImageData(x, y, width, height);
                                       ^^^^^^^^^^^^ not limited to one

Сега вашият буфер за данни ще съдържа всички пиксели за дадения регион. За да получите цялото платно:

var imageData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);

Регулирайте ги и поставете обратно в същата позиция:

ctx.putImageData(imageData, x, y);

и сте готови.

Не забравяйте, че всеки пиксел се състои от четири байта (RGBA). За да адресирате по-голям буфер, можете да направите:

function getPixelIndex(x, y) {
    return (y * width + x) * 4; // width used when getting buffer
}

Съвети:

  • ако планирате често да актуализирате един и същ буфер, просто извлечете буфера веднъж и запазете указател към него, актуализирайте го, когато имате нужда и го поставете обратно, след което използвайте отново същия буфер. По този начин спестявате време за получаване на буфера. Това няма да работи, ако междувременно приложите графики към платното със стандартни методи.
  • Можете също да започнете с празен буфер, като използвате createImageData() вместо getImageData().
  • Ако вашите пикселни цветови данни са повече или по-малко статични, можете да актуализирате буфера, като използвате Uint32Array вместо Uint8ClampedArray. Получавате 32-битова версия като тази, след като получите imageData:

    var buffer32 = new Uint32Array(imageData.data.buffer);

Вашият нов buffer32 ще сочи към същия основен байтов буфер, така че няма значително претоварване на паметта, но ви позволява да четете и записвате 32-битови стойности вместо само 8-битови. Просто имайте предвид, че редът на байтовете (обикновено) е от малък ред, така че подредете байтовете като ABGR. След това направете както преди, обадете се на ctx.putImageData(imageData, x, y);, когато трябва да актуализирате.

person Community    schedule 05.11.2014