canvas | Манипуляции с пикселями — efim360.ru

canvas | Манипуляции с пикселями

Для веб-разработчиков (не нормативно)

imagedata = new ImageData(swsh [, settings])

Возвращает объект ImageData с заданными размерами и цветовым пространством, указанным в настройках settings. Все пиксели в возвращаемом объекте прозрачно-чёрные.

Выдает исключение DOMException "IndexSizeError", если любой из аргументов ширины или высоты равен нулю.

imagedata = new ImageData(datasw [, sh [, settings ] ])

Возвращает объект ImageData, используя данные, предоставленные в аргументе Uint8ClampedArray, интерпретированные с использованием заданных размеров и цветового пространства, указанного настройками settings.

Поскольку каждый пиксель в данных представлен четырьмя числами, длина данных должна быть кратна заданной ширине в четыре раза. Если также указана высота, то длина должна быть точно равна ширине, умноженной на высоту, умноженную на 4.

Выдает DOMException "IndexSizeError", если заданные данные и измерения не могут быть интерпретированы последовательно или если какое-либо измерение равно нулю.

imagedata = context.createImageData(imagedata)

Возвращает объект ImageData с теми же размерами и цветовым пространством, что и аргумент. Все пиксели в возвращаемом объекте прозрачно-чёрные.

imagedata = context.createImageData(swsh [, settings])

Возвращает объект ImageData с заданными размерами. Цветовое пространство возвращаемого объекта является цветовым пространством контекста, если только оно не переопределено настройками settings. Все пиксели в возвращаемом объекте прозрачно-чёрные.

Выдает исключение DOMException "IndexSizeError", если любой из аргументов ширины или высоты равен нулю.

imagedata = context.getImageData(sxsyswsh [, settings])

Возвращает объект ImageData, содержащий данные изображения для заданного прямоугольника растрового изображения. Цветовое пространство возвращаемого объекта является цветовым пространством контекста context, если только оно не переопределено настройками settings.

Выдает DOMException "IndexSizeError", если любой из аргументов ширины или высоты равен нулю.

imagedata.width

imagedata.height

Возвращает фактические размеры данных в объекте ImageData в пикселях.

imagedata.data

Возвращает одномерный массив, содержащий данные в порядке RGBA, в виде целых чисел в диапазоне от 0 до 255.

imagedata.colorSpace

Возвращает цветовое пространство пикселей.

context.putImageData(imagedatadxdy [, dirtyXdirtyYdirtyWidthdirtyHeight ])

Закрашивает данные из данного объекта ImageData в растровое изображение. Если предоставлен грязный прямоугольник, закрашиваются только пиксели из этого прямоугольника.

Атрибуты globalAlpha и globalCompositeOperation, а также теневые атрибуты игнорируются для целей вызова этого метода; пиксели в холсте заменяются целиком, без композиции, альфа-смешивания, теней и т. д.

Выдает исключение DOMException "InvalidStateError", если внутренний слот [[ViewedArrayBuffer]] значения атрибута data объекта imagedata отсоединен.


Объекты, реализующие интерфейс CanvasImageData, предоставляют следующие методы для чтения и записи данных пикселей в растровое изображение.

Шаги конструктора new ImageData(swshsettings):

1. Если один или оба из sw и sh равны нулю, выдаётся исключение DOMException "IndexSizeError".
2. Инициализируйте this (объект контекста) заданный sw, sh и settings, установленные в settings.
3. Инициализируйте данные изображения изображения this (объект контекста) прозрачным чёрным цветом.

 

Шаги конструктора new ImageData(dataswshsettings):

1. Пусть длина length будет количеством байтов в данных data.
2. Если длина length не является ненулевым целым числом, кратным четырем, генерируется исключение DOMException "InvalidStateError".
3. Пусть длина length равна длине length, деленной на четыре.
4. Если длина length не является целым числом, кратным sw, то генерируется исключение DOMException "IndexSizeError".
Примечание

На этом шаге длина гарантированно больше нуля (иначе второй шаг выше прервал бы шаги), поэтому, если sw равно нулю, этот шаг вызовет исключение и возврат.

5. Пусть высота height равна длине length, деленной на sw.
6. Если задано значение sh и его значение не равно высоте height, то выдаётся исключение DOMException "IndexSizeError".
7. Инициализируйте this (объект контекста) заданный sw, sh, настройки settings, установленные в настройки settings, и источник source, установленный в данные data.
Примечание

Этот шаг не устанавливает для данных this (объект контекста) копию данных data. Он устанавливает фактический объект Uint8ClampedArray, переданный в качестве данных data.


Шаги метода createImageData(swshsettings):

1. Если один или оба из sw и sh равны нулю, выдается исключение DOMException "IndexSizeError".
2. Пусть newImageData будет новым объектом new ImageData.
3. Инициализируйте newImageData, учитывая абсолютную величину sw, абсолютную величину sh, настройки, установленные в settings, и defaultColorSpace, установленные в цветовое пространство объекта контекста (this).
4. Инициализируйте данные изображения newImageData прозрачным чёрным цветом.
5. Вернуть newImageData.

 

Шаги метода createImageData(imagedata):

1. Пусть newImageData будет новым объектом ImageData.
2. Инициализируйте newImageData, учитывая значение атрибута ширины width данных изображения imagedata, значение атрибута высоты height данных изображения imagedata и значение defaultColorSpace, равное значению атрибута colorSpace данных изображения imagedata.
3. Инициализируйте данные изображения newImageData прозрачным чёрным цветом.
4. Вернуть newImageData.

 

Шаги метода getImageData(sx, sy, sw, sh, settings):

1. Если аргументы sw или sh равны нулю, генерируется исключение DOMException "IndexSizeError".
2. Если для флага очистки источника объекта CanvasRenderingContext2D установлено значение false, создайте исключение DOMException "SecurityError".
3. Пусть imageData будет новым объектом ImageData.
4. Инициализируйте imageData с учетом sw, sh, настроек, установленных в settings, и defaultColorSpace, установленного в цветовое пространство объекта контекста (this).
5. Пусть исходным прямоугольником будет прямоугольник, углами которого являются четыре точки (sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh).
6. Задайте значения пикселей imageData как пиксели выходного растрового изображения объекта контекста (this) в области, заданной исходным прямоугольником в единицах координатного пространства растрового изображения, преобразованные из цветового пространства объекта контекста (this) в colorSpace объекта imageData с использованием 'relative-colorimetric' (относительно-колориметрического) способа визуализации (рендеринга).
7. Установите значения пикселей imageData для областей исходного прямоугольника, которые находятся за пределами выходного растрового изображения, на прозрачный чёрный.
8. Вернуть imageData.

 

Чтобы инициализировать объект ImageData (initialize an ImageData object) imageData, учитывая положительное целое число строк rows, положительное целое число пикселей в строке pixelsPerRow, необязательные настройки (settings) ImageDataSettings, необязательный источник (source) Uint8ClampedArray и необязательный (defaultColorSpace) PredefinedColorSpace:

1. Если источник source был указан, то инициализируйте атрибут данных data объекта imageData для источника source.
2. В противном случае (источник source не указан) инициализируйте атрибут данных data из imageData новым объектом Uint8ClampedArray. Объект Uint8ClampedArray должен использовать новый Canvas Pixel ArrayBuffer для своего хранения и должен иметь нулевое начальное смещение и длину, равную длине его хранилища в байтах. Canvas Pixel ArrayBuffer должен иметь правильный размер для хранения строк rows × пикселей на строку pixelsPerRow пикселей.

  Если Canvas Pixel ArrayBuffer не может быть выделен, повторно сгенерируйте ошибку RangeError, выданную JavaScript, и вернитесь.

3. Инициализируйте атрибут ширины width из imageData равным pixelsPerRow.
4. Инициализируйте атрибут высоты height из imageData для строк rows.
5. Если параметры settings были заданы и settings["colorSpace"] существуют, то инициализируйте атрибут colorSpace в imageData значением settings["colorSpace"].
6. В противном случае, если задано значение defaultColorSpace, инициализируйте атрибут colorSpace объекта imageData значением defaultColorSpace.
7. В противном случае инициализируйте атрибут colorSpace объекта imageData значением "srgb".

 

Объекты ImageData являются сериализуемыми объектами. Их шаги сериализации, заданные значением value и сериализованные serialized, таковы:

1. Установите serialized.[[Data]] на суб-сериализацию значения атрибута данных data значения value.
2. Установите serialized.[[Width]] значение атрибута ширины width значения value.
3. Установите serialized.[[Height]] значение атрибута высоты height значения value.
4. Установите serialized.[[ColorSpace]] значение атрибута colorSpace значения value.

 

Их шаги десериализации с учетом сериализации serialized и значения value:

1. Инициализируйте атрибут данных data значения value для суб-десериализации serialized.[[Data]].
2. Инициализируйте атрибут ширины width значения value как serialized.[[Width]].
3. Инициализируйте атрибут высоты height значения value как serialized.[[Height]].
4. Инициализируйте атрибут colorSpace colorSpace значения value для serialized.[[ColorSpace]].

 

Canvas Pixel ArrayBuffer — это ArrayBuffer, данные которого представлены в порядке слева направо, строка за строкой сверху вниз, начиная с левого верхнего угла, причем красный, зелёный, синий и альфа-компоненты каждого пикселя задаются в этом порядке для каждого пикселя. Каждый компонент каждого пикселя, представленного в этом массиве, должен находиться в диапазоне 0..255, представляя 8-битное значение для этого компонента. Компонентам должны быть присвоены последовательные индексы, начинающиеся с 0 для красного компонента верхнего левого пикселя.

Метод putImageData() записывает данные из структур ImageData обратно в выходное растровое изображение контекста рендеринга. Его аргументы: imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth и dirtyHeight.

Когда последние четыре аргумента этого метода опущены, предполагается, что они имеют значения 0, 0, элемент ширины width структуры данных изображения и элемент высоты height структуры данных изображения соответственно.

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

1. Пусть буфер buffer будет внутренним слотом [[ViewedArrayBuffer]] значения атрибута данных data объекта imagedata.
2. Если IsDetachedBuffer(buffer) имеет значение true, создайте исключение DOMException "InvalidStateError".
3. Если dirtyWidth отрицательное значение, то пусть dirtyX будет dirtyX+dirtyWidth, а dirtyWidth будет равен абсолютной величине dirtyWidth.
  Если dirtyHeight отрицательное значение, то пусть dirtyY будет dirtyY+dirtyHeight, а dirtyHeight будет равен абсолютной величине dirtyHeight.
4. Если dirtyX отрицательно, то пусть dirtyWidth будет dirtyWidth+dirtyX, а dirtyX будет равен нулю.
  Если dirtyY отрицательно, то пусть dirtyHeight будет dirtyHeight+dirtyY, а dirtyY будет равен нулю.
5. Если dirtyX+dirtyWidth больше атрибута ширины width аргумента imagedata, то пусть dirtyWidth будет значением этого атрибута ширины width за вычетом значения dirtyX.
  Если dirtyY+dirtyHeight больше атрибута высоты height аргумента imagedata, то пусть dirtyHeight будет значением этого атрибута высоты height за вычетом значения dirtyY.
6. Если после этих изменений либо dirtyWidth, либо dirtyHeight отрицательны или равны нулю, то возвращаются, не затрагивая растровые изображения.
7. Для всех целых значений x и y, где dirtyXx < dirtyX+dirtyWidth и dirtyYy < dirtyY+dirtyHeight, скопируйте четыре канала пикселя с координатой (x, y) в Canvas Pixel ArrayBuffer структуры данных изображения в пиксель. с координатой (dx+x, dy+y) в выходном растровом изображении контекста рендеринга.

 

Примечание

Из-за потерь при преобразовании между цветовыми пространствами и преобразовании в и из предварительно умноженных значений альфа-цвета пиксели, которые были только что установлены с помощью putImageData() и не являются полностью непрозрачными, могут быть возвращены в эквивалентный getImageData() как разные значения.

Текущий путь, матрица преобразования, атрибуты тени, глобальный альфа-канал, область отсечения и глобальный оператор композиции не должны влиять на методы, описанные в этом разделе.

 

Пример

В следующем примере сценарий создает объект ImageData, чтобы он мог рисовать на нём.

// холст canvas является ссылкой на элемент <canvas>

let context = canvas.getContext('2d');

 

// создать чистый лист

let data = context.createImageData(canvas.width, canvas.height);

 

// создать немного плазмы

FillPlasma(data, 'green'); // зелёная плазма

 

// добавить облако в плазму

AddCloud(data, data.width/2, data.height/2); // поставить облако посередине

 

// рисуем плазму+облако на холсте

context.putImageData(data, 0, 0);

 

// методы поддержки

function FillPlasma(data, color) { ... }

function AddCloud(data, x, y) { ... }

 

Пример

Вот пример использования getImageData() и putImageData() для реализации фильтра обнаружения границ.

<!DOCTYPE HTML>

<html lang="en">

 <head>

  <title>Демонстрация обнаружения границo</title>

  <script>

   var image = new Image();

   function init() {

     image.onload = demo;

     image.src = "image.jpeg";

   }

   function demo() {

     var canvas = document.getElementsByTagName('canvas')[0];

     var context = canvas.getContext('2d');

 

     // нарисовать изображение на холсте

     context.drawImage(image, 0, 0);

 

     // получить данные изображения для манипулирования

     var input = context.getImageData(0, 0, canvas.width, canvas.height);

 

     // получить пустой лист, чтобы поместить данные в

     var output = context.createImageData(canvas.width, canvas.height);

 

     // псевдоним некоторых переменных для удобства

     // В этом случае input.width и input.height

     // сопоставьте canvas.width и canvas.height

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

     var w = input.width, h = input.height;

     var inputData = input.data;

     var outputData = output.data;

 

     // обнаружение края

     for (var y = 1; y < h-1; y += 1) {

       for (var x = 1; x < w-1; x += 1) {

         for (var c = 0; c < 3; c += 1) {

           var i = (y*w + x)*4 + c;

           outputData[i] = 127 + -inputData[i - w*4 - 4] - inputData[i - w*4] - inputData[i - w*4 + 4] +

                                 -inputData[i - 4] +     8*inputData[i]       - inputData[i + 4] +

                                 -inputData[i + w*4 - 4] - inputData[i + w*4] - inputData[i + w*4 + 4];

         }

         outputData[(y*w + x)*4 + 3] = 255; // alpha

       }

     }

 

     // вернуть данные изображения обратно после манипуляции

     context.putImageData(output, 0, 0);

   }

  </script>

 </head>

 <body onload="init()">

  <canvas></canvas>

 </body>

</html>

 

Пример

Вот пример преобразования цветового пространства, применяемого при рисовании сплошным цветом и обратном считывании результата с помощью и getImageData().

<!DOCTYPE HTML>

<html lang="ru">

<title>Демонстрация данных изображения цветового пространства</title>

 

<canvas></canvas>

 

<script>

const canvas = document.querySelector('canvas');

const context = canvas.getContext('2d', {colorSpace:'display-p3'});

 

// Нарисуйте красный прямоугольник. Обратите внимание,

// что шестнадцатеричная нотация цвета определяет цвета sRGB.

context.fillStyle = "#FF0000";

context.fillRect(0, 0, 64, 64);

 

// Получите данные изображения.

const pixels = context.getImageData(0, 0, 1, 1);

 

// Это напечатает «display-p3», отражая поведение по умолчанию

// при возврате данных изображения в цветовом пространстве холста.

console.log(pixels.colorSpace);

 

// Это напечатает значения 234, 51 и 35,

// отражающие красный цвет заливки, преобразованные в «display-p3».

console.log(pixels.data[0]);

console.log(pixels.data[1]);

console.log(pixels.data[2]);

</script>

 

 

 

Информационные ссылки

Стандарт HTML - Раздел "4.12.5.1.15 Pixel manipulation" - https://html.spec.whatwg.org/multipage/canvas.html#pixel-manipulation

Поделись записью