Pull to refresh

Знакомство с Adobe Pixel Bender (Часть 1)

Reading time 4 min
Views 9.5K
Технология Pixel Bender была разработана в лаборатории Adobe, для создания фильтров предназначенных для обработки видео и изображений. Фильтры Pixel Bender(PB) могут использоваться в программных продуктах: Adobe Flash, Adobe Flex, Adobe Photoshop, Adobe After Effects. По своей сути, PB предоставляет возможность программным способом обрабатывать изображения с поддержкой аппаратного ускорения. Он хорош тем, что позволяет обработать каждый пиксель поэтапным обходом изображения.
Pixel Bender Toolkit абсолютно бесплатен, скачать его можно по следующей ссылке labs.adobe.com/technologies/pixelbender. PBT(Pixel Bender Toolkit) включает в себя: интегрированную среду разработки с поддержкой родного си-подобного языка и граф-языка, примеры фильтров, документацию.
Создание фильтров делится на 3 этапа:
  • Разработка алгоритма
  • Запись алгоритма в PBT
  • Экспорт в байт-код


Приступаем к написанию фильтров. Запускаем программу. Создаем новый фильтр (File>New Kernel Filter) В редакторе кода появляется код:
image
В тэге languageVersion требуется указать версию языка. В тэге kernel находится описание фильтра: автор, версия, namespace разработчика, характеристики.
input image4 src;
Данная строчка говорит о том, что входное изображение src имеет тип image4. Тип image4 имеет 4 свойства: a(прозрачность), b(синий канал), g(зеленый канал), r(красный канал).
Т.к. обработанное изображение мы будем выводить по 1-ому пикселю. Нам следует указать тип и название обработанного пикселя. В данном случае пиксель dst будет иметь тип pixel4.
output pixel4 dst;
Функция evaluatePixel() будет вызываться для каждого пикселя. Если функция не будет возвращать переменные, следует указать void. Для того, чтобы узнать какой пиксель обрабатывается в данный момент нужно использовать outCoord(), это переменная типа float2, вектор, у которого два свойства: X и Y. Функция sampleNearest(изображение, координаты); возвращает пиксель(pixel4) в координатах указанного изображения.
В строчке dst = sampleNearest(src, outCoord());, мы присваиваем пиксель, находящийся на изображении src в координатах outCoord().x, outCoord().y. После запуска фильтра (кнопка Run) мы видим, что изображение не изменилось, т.к. мы банально скопировали пиксели. Теперь попробуем изменить эту ситуацию.
Не секрет, что осветлить изображение можно путем повышения значений каналов. В функции evaluatePixel напишем:
dst += sampleNearest(src,outCoord());
dst += sampleNearest(src,outCoord());
dst += sampleNearest(src,outCoord());

Нажимаем кнопку Run и увидим, что изображение стало светлее. Теперь попробуем сместить наше изображение на 10 пикселей выше и на 15 пикселей левее. Для этого в evaluatePixel пишем:
dst = sampleNearest(src,outCoord()+float2(15,10));
По правилу свизлинга, который реализован в PB, получиться так:
dst = sampleNearest(src,float2(outCoord().x + 15, outCoord().y + 10);
Как вы уже догадались, ось ординат направлена вверх, ось абсцисс влево.
Теперь попробуем заполнить пиксели в координате x меньше 50, пикселями в координате x=50;
Пишем в функции evaluatePixel:
if(outCoord().x<float(50))
{
dst = sampleNearest(src,float2(float(50), outCoord().y));
}
else
{
dst = sampleNearest(src, outCoord());
}

image
Теперь попробуем создать пучок света на изображении.
Как говорилось выше, чтобы сделать пиксель светлее нужно увеличить значение его каналов.
Возьмем случайную координату пучка света, допустим, это будет параметр
float2 center = float2(100,100);
Придумаем размер свечения 200. Далее слудет делить размер свечения на расстояние от его центра до текущего пикселя.
dst = 200/distance(outCoord(), center) * sampleNearest(src, outCoord());
image
Допустим, нам требуется сделать пиксели размером 5x5. Цвет этого большого пикселя мы будем брать из его верхнего левого угла. По мере обхода пикселей, мы будем делить каждую координату на размер большого пикселя, тем самым мы узнаем, его номер в двумерном массиве (m, n). Далее нужно умножить m и n на размер большого пикселя, для того, чтобы узнать координату верхнего левого угла.
float2 sc = floor(outCoord() / float2(5, 5));
sc *= 5;
dst = sampleNearest(src, sc);

image
Теперь попробуем реализовать блур.
Создадим «контейнер» в который будем добавлять наше изображение со смещением.
float4 outpixel;
outpixel += sampleNearest(src,outCoord()+float2(1,1));
// Сместили влево, вверх
outpixel += sampleNearest(src,outCoord()+float2(1,-1)); // Сместили влево, вниз
outpixel += sampleNearest(src,outCoord()+float2(-1,1)); // Сместили вправо, вверх
outpixel += sampleNearest(src,outCoord()+float2(-1,-1)); // Сместили влево, вниз
dst = outpixel / float(4.0); // Выводим полученный пиксель, не забывая уменьшить значение канала путем деления. Если мы не уменьшим, то изображение получиться яркое и контрастное.
Вот результат:
image
Фильтр crossStitch:
imageimage
Его можно найти в Adobe Pixel Bender Exchange. Немного подумаем по поводу реализации. Сам фильтр превращает картинку в сетку, т.е. на выходе изображение содержит меньше половины пикселей чем оригинал. Следовательно по мере обхода каждого пикселя входящего изображения (функция evaluatePixel) будем смотреть координаты, если пиксель лежит на диагонали квадрата размером size(динамический параметр), то его выводим. Смотрим на реализацию.
image

Вывод: С PB можно реализовать любые эффекты. Помогает в повышении производительности RIA-приложений. Незаменимый инструмент для программистов, которые работают с графикой. Научившись обрабатывать изображения в Pixel Bender, вы сэкономите большое кол-во времени в будущем.

Где брать готовые фильтры?
Adobe Pixel Bender Exchange Site www.adobe.com/cfusion/exchange/index.cfm?event=productHome&exc=26
Petri Leskinen pixelero.wordpress.com/category/pixel-bender
Mrdoob www.mrdoob.com/blog/post/586
Kevin GoldSmith blogs.adobe.com/kevin.goldsmith
За крутыми алгоритмами лазить сюда iquilezles.org/www/index.htm

Автор: Сергей Flastar Гончар flash-разработчик flastar.ru/blog
Tags:
Hubs:
+29
Comments 31
Comments Comments 31

Articles