вторник, 28 октября 2014 г.

Как применить фильтры и эффекты к изображению при помощи javascript и canvas?

Элемент <canvas> (холст) полностью поддерживается IE, начиная с 9 версии. Canvas предназначен для создания и обработки различной растровой графики при помощи JavaScript. Кроме этого его можно использовать для работы с анимацииями и даже обработки видео в реальном времени.

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

// создаем или находим изображение
var img = document.getElementById('img');

img.onload = function() {
  // создаем или находим canvas
  var canvas = document.getElementById('canvas');
  // получаем его 2D контекст
  var context = canvas.getContext('2d');
  // помещаем изображение в контекст
  context.drawImage(img, 0, 0);
  // получаем объект, описывающий внутреннее состояние области контекста
  var imageData = context.getImageData(0, 0, 300, 300);
  // фильтруем
  imageDataFiltered = sepia(imageData);
  // кладем результат фильтрации обратно в canvas
  context.putImageData(imageDataFiltered, 0, 0);
}

img.src = 'img/girl.png';

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

var sepia = function (imageData) {
  // получаем одномерный массив, описывающий все пиксели изображения
  var pixels = imageData.data;
  // циклически преобразуем массив, изменяя значения красного, зеленого и синего каналов
  for (var i = 0; i < pixels.length; i += 4) {
    var r = pixels[i];
    var g = pixels[i + 1];
    var b = pixels[i + 2];
    pixels[i]     = (r * 0.393)+(g * 0.769)+(b * 0.189); // red
    pixels[i + 1] = (r * 0.349)+(g * 0.686)+(b * 0.168); // green
    pixels[i + 2] = (r * 0.272)+(g * 0.534)+(b * 0.131); // blue
  }
  return imageData;
};

pixels – это одномерный массив, в котором последовательно представлены значения красного, зеленого, синего канала, а также канала прозрачности для каждого пикселя изображения. Графически его можно представить так:


В итоге получится следующее преобразование картинки:


Достоинства Canvas:
- поддерживается IE 9 и практически всеми мобильными браузерами;
- множество готовых решений, библиотек, плагино;
- фильтры могут быть настолько сложными и нестандартными, насколько у вас хватит фантазии и насколько вы разбираетесь в - цифровой обработке изображений.

Недостатки Canvas:
- Нельзя обработать картинки с других доменов (включая поддомены) из-за ограничений безопасности браузера. Это довольно легко решается проксированием или переводом в base64, но как бы то ни было, создает дополнительные проблемы. Хотя проксирование не всегда не всегда нужно, поскольку сервер может отдавать заголовки (CORS), которые разрешают конкретному сайту (домену) или всем использовать свои ресурсы. Тогда проблем с другим доменом не будет. Ведь мы можем хранить наши изображения в CDN и проксирование будет не эффективным. Так же конвертация в base64 и обратно – не быстрая операция. И при конвертации base64 -> image такому изображение ставится текущий домен в качестве origin. Это так же может помешать смешать два изображения с разных доменов.
Для того, чтобы не было проблем с быстродействием, можно выносить обработку изображения в Web Worker'ы.
Об этом почитать можно тут http://blogs.msdn.com/b/eternalcoding/archive/2012/09/20/using-web-workers-to-improve-performance-of-image-manipulation.aspx
Если обработка не требует соседних пикселей (как серпия, например), то можно даже распараллелить обработку по нескольким worker'ам.
- Если мы говорим про сложные фильтры, то это медленная, последовательная, блокирующая операция. Десктопный браузер при этом подтормаживает, а мобильный браузер серьезно тупит.

Комментариев нет:

Отправить комментарий