Данные изображений

Данные изображений.

Сказав, что drawImage() — единственный метод, способный выводить изображения на холст, мы солгали. Существует еще несколько мощных методов, предназначенных для обработки изображений, которые также умеют визуализировать результат. Но поскольку они работают не с изображениями, а с данными, предыдущее заявление следует считать истинным. И все же зачем нам обрабатывать данные вместо изображений?

Каждое изображение можно представить в виде последовательности целых чисел, соответствующих компонентам RGBA (по четыре значения на каждый пиксел). Группа значений, несущих такую информацию, составляет одномерный массив, на основе которого можно сгенерировать изображение. API Canvas (Холст) предлагает три метода для манипулирования такими данными и обработки изображений:

— TgetImageData(x, y, width, height). Считывает прямоугольную часть холста с размерами, определенными в свойствах, и преобразует ее в массив данных. Возвращает объект, к которому затем можно обращаться через свойства width, height и data;

— putImageData(imagedata, x, y). Превращает данные, на которые ссылается imagedata, в изображение и выводит его на холст в позиции с координатами x и y. Таким образом, это противоположность метода getImageData();

— createImageData(width, height). Создает данные для пустого изображения. Все пикселы пустого изображения черного цвета и полностью прозрачные. Он также может принимать данные изображения через атрибут (который указывается вместо атрибутов width и height) и в таком случае возвращает размеры изображения, описываемого этими данными.

Позиция каждого из значений в массиве вычисляется по формуле (width ■ 4 ■ y) + (x ■ 4). Результат вычисления соответствует первому компоненту пиксела (красному цвету). Для получения позиций остальных компонентов к результату необходимо прибавлять по единице для каждого компонента. Например, (width ■ 4 ■ y) + (x ■ 4) + 1 указывает на зеленый компонент, (width ■ 4 ■ y) + (x ■ 4) + 2 — на синий, а (width ■ 4 ■ y) + + (x ■ 4) + 3 — на компонент альфа-канала. Давайте рассмотрим пример.

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

Метод getImageData() работает правильно только в том случае, когда документ и изображение принадлежат одному и тому же источнику (URL). Таким образом, для тестирования этого примера вам необходимо сохранить изображение с нашего сервера, расположенное по адресу http://www. minkbooks. com/content/snow. jpg, на своем компьютере (или использовать собственное изображение), а затем загрузить изображение, HTML-файл и JavaScript-файл на собственный сервер. Если вы всего лишь сохраните файл на своем компьютере и попробуете открыть пример в браузере, он не сработает.

Листинг 7.25. Создание негатива изображения

Function initiate(){

Var elem=document. getElementById(‘canvas’); canvas=elem. getContext(‘2d’);

Var img=new Image(); img. src="snow. jpg";

Img. addEventListener("load", modimage, false);

}

Function modimage(e){ img=e. target;

Canvas. drawlmage(img,0,0);

Var info=canvas. getImageData(0,0,175,262);

Var pos;

For(x=0;x<=175;x++){

For(y=0;y<=262;y++){

Pos=(info. width*4*y)+(x*4);

Info. data[pos]=255-info. data[pos];

Info. data[pos+1]=255-info. data[pos+1];

Info. data[pos+2]=255-info. data[pos+2];

}

}

Canvas. putImageData(info,0,0);

}

Window. addEventListener("load", initiate, false);

На этот раз для обработки изображения после загрузки нам пришлось создать новую функцию (вместо того чтобы использовать анонимную). Сначала функция modimage() создает ссылку на изображение посредством свойства target, которое мы уже использовали в предыдущих примерах. Затем с помощью этой ссылки и метода drawImage() изображение выводится на холст в точке (0, 0). В этой части кода ничего необычного не происходит, но скоро все изменится.

Для того чтобы этот пример работал правильно, вам понадобится загрузить на свой сервер все файлы для него (включая файл snow. jpg, который вы можете найти по адресу http:// www.minkbooks.com/content/snow.jpg).

Ширина изображения в примере равна 350 пикселам, а высота — 262 пикселам, поэтому, передавая методу getImageData() координату верхнего левого угла (0, 0) и смещение по горизонтали и вертикали 175 и 262 пиксела соответственно, мы вырезаем только левую половину исходного изображения. Вырезанные данные изображения сохраняются в переменной info.

После того как нужная информация собрана, необходимо обработать каждый пиксел, для того чтобы получить желаемый результат (мы хотим получить негатив исходного изображения).

Для описания каждого цвета используется значение от 0 до 255; таким образом, для того чтобы получить негатив любого цвета, нужно вычесть его значение из 255, используя формулу цвет = 255 — цвет. Необходимо выполнить эти вычисления для каждого пиксела изображения, и с этой целью мы создали два цикла: один для столбцов, второй для строк. В циклах мы обрабатываем каждый пиксел, вычисляя соответствующее значение негатива. Обратите внимание на то, что цикл for для значений x начинается с 0 и заканчивается 175 (что соответствует ширине той части изображения, которую мы вырезали из холста), а цикл для значений y начинается с 0 и заканчивается 262 (что соответствует высоте исходного изображения и высоте вырезанной части).

После того как все пикселы пройдут обработку, переменная info с новыми данными изображения отправляется на холст посредством метода putImageData(). Обработанное изображение выводится в той же позиции, в которой находится исходное. Таким образом, только что созданный негатив заменяет левую половину исходного изображения.

Метод getImageData() возвращает объект, который можно обработать, обратившись к его свойствам (width, height и data), или сразу же передать методу putImageData(), не добавляя шаг обработки. Существует еще один способ извлечения данных холста, который возвращает его содержимое в форме закодированной в системе base64 строки. Эту строку в дальнейшем можно использовать в качестве источника для другого холста или HTML-элементов, подобных <img>, а можно отправить на сервер или сохранить в виде файла. Для этой цели в API существует специальный метод toDataURL(type). У элемента <canvas> есть два свойства, width и height, и два метода, getContext() и toDataURL(). Второй метод возвращает URL данных (data:url), содержащий представление содержимого холста в формате PNG (или в другом формате изображения, указанном в атрибуте type).

Чуть позже мы рассмотрим несколько примеров использования toDataURL() и узнаем, как с помощью этого метода интегрировать API Canvas (Холст) с другими API.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *