21.4.14. Манипулирование пикселами

We use cookies. Read the Privacy and Cookie Policy

Метод getlmageData() возвращает объект ImageData, представляющий массив пикселов (в виде компонентов R, G, В и А) из прямоугольной области холста. Создать пустой объект ImageData можно с помощью метода createImageData(). Пикселы в объекте ImageData доступны для записи, благодаря чему их можно изменить как угодно и затем скопировать обратно в холст вызовом метода putlmageData().

Эти методы манипулирования пикселами предоставляют низкоуровневый доступ к холсту. Координаты и размеры области, передаваемой методу getlmageData(), задаются в системе координат по умолчанию: ее размеры измеряются в CSS-пикселах и без учета текущего преобразования. При вызове метода putlmageData() координаты также задаются в системе координат по умолчанию. Кроме того, метод putImageData() игнорирует все графические атрибуты. Он не использует механизм композиции, не умножает пикселы на значение свойства globalAlpha и не рисует тени.

Методы манипулирования пикселами могут пригодиться для реализации обработки изображений. Пример 21.10 демонстрирует, как создать простейший эффект размытия или «смазывания» быстро движущегося объекта в элементе <canvas>~ Пример демонстрирует применение методов getlmageData() и putlmageData() и показывает, как выполнять итерации по пикселам в объекте ImageData и изменять их значения, но без подробного описания. Полная информация о методах getlmageData() и putlmageData() приводится в справочной статье CanvasRenderingContext2D, а подробное описание объекта ImageData - в его собственной справочной статье.

Пример 21.10. Создание эффекта размытия быстродвижущегося объекта с помощью объекта ImageData

// "Смазать" пикселы прямоугольной области вправо, чтобы воспроизвести эффект быстрого

// движения объекта справа налево. Значение п должно быть равно или больше 2. Нем больше

// значение, тем сильнее эффект смазывания. Координаты и размеры прямоугольной области

// задаются в системе координат по умолчанию,

function smear(c, п, х, у, w, h) {

  // Получить объект ImageData, представляющий пикселы области эффекта

  var pixels = c.getImageData(x,у,w,h);

  // Смазывание выполняется на месте, и потому требуется получить только

  // исходный объект ImageData. Некоторые алгоритмы обработки изображений требуют

  // использования дополнительного объекта ImageData для сохранения трансформированных

  // значений пикселов. Если бы потребовался промежуточный буфер вывода, можно было бы

  // создать новый объект ImageData с теми же размерами следующим способом:

  // var output_pixels = с.createlmageData(pixels):

  // Эти размеры могут отличаться от значений аргументов w и h: на каждый

  // CSS-пиксел может приходиться несколько аппаратных пикселов,

  var width = pixels.width,

      height = pixels.height:

  // Это массив байтов, хранящий информацию о пикселах, слева направо и сверху вниз.

  // Для каждого пиксела отводится 4 последовательных байта, в порядке R,G,В,А.

  var data = pixels.data;

  // Смазать каждый пиксел после первого в каждой строке, заменив его суммой

  // 1/n-й доли его собственного значения и m/n-й доли значения предыдущего пиксела

  var m = n-1;

  for(var row = 0; row < height: row++) { // Для каждой строки

    var і = row*width*4 +4; // Индекс второго пиксела в строке

    for(var col = 1; col < width; col++, і += 4) { // Для каждого столбца

      data[i] = (data[і] + data[i-4]*m)/n; // Красная составляющая

      data[i+1] = (data[i+1] + data[i-3]*m)/n; // Зеленая

      data[i+2] = (data[i+2] + data[i-2]*m)/n; // Синяя

      data[i+3] = (data[i+3] + data[i-1]*m)/n; // Альфа-составляющая

    }

  }

  // Скопировать смазанное изображение обратно в ту же позицию в холсте

  с.putImageData(pixels, х, у);

}

Обратите внимание, что на метод getImageData() накладываются те же ограничения политики общего происхождения, что и на метод toDataURL(): он не будет работать с холстами, в которые вставлялись изображения (непосредственно, вызовом метода drawImage(), или косвенно, с помощью метода CanvasPattern), имеющие происхождение, отличное от происхождения документа, содержащего элемент <canvas>.