Вставка нескольких пикселей изображения холста

Я получаю пиксели в данных изображения холста, и я делаю это много.

Я думаю, что вставка и извлечение данных изображения холста требует больших затрат времени процессора, поэтому я хочу сделать их как можно меньше.

Один из способов сократить это — сделать одну вставку, которая будет вставлять несколько пикселей в одну последовательность, но до сих пор я не мог увидеть, как это будет сделано. Все примеры, которые я видел до сих пор, извлекают и вставляют только один пиксель.

Итак, вопрос в том, чтобы ускорить манипулирование пикселями изображения холста, как мне вставлять/извлекать несколько пикселей одновременно?


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