Как стать автором
Обновить

Используем фильтр PixelBender'а для двух картинок во Flex

Время на прочтение5 мин
Количество просмотров698
Still Dre

Вот такой незамысловатый эффект получился при использовании pixel bender'а.

На самом деле такой эффект я впервые увидел у Andre Michelle, но сорсов он не выложил. В те времена я написал его на восьмом плеере (AS2), но с выходом новых возможностей решил повторить эксперимент. Обошлось не без приключений, зато код получился без граблей, которые приходилось строить в восьмерке.

Смотреть тут. (5 мб)


Пишем фильтр


Переменные:
src — первая входная картинка
src2 — вторая входная картинка
white — белый цвет
black — черный цвет
min — значение по которому определяем ставить белый или черный цвет в выходящее изображение

Логика фильтра такова:
— (a1) берем цвет первого пикселя первой картинки
— (a2) берем цвет первого пикселя второй картинки
— (ss) вычитаем из a1 a2
— если разница каждого цвета ss больше min тогда в выходящей картинке на месте первого пикселя будет белый цвет иначе черный
  1. <languageVersion : 1.0;>
  2.  
  3. kernel NewFilter
  4. namespace : "Your Namespace";
  5.   vendor : "Your Vendor";
  6.   version : 1;
  7.   description : "your description";
  8. >
  9. {
  10.   input image4 src;
  11.   input image4 src2;
  12.   output pixel4 dst;
  13.   
  14.   const pixel4 white = float4(1.0, 1.0, 1.0, 1.0);
  15.   const pixel4 black = float4(0.0, 0.0, 0.0, 0.0);
  16.   const float min = 0.05;
  17.  
  18.   void
  19.   evaluatePixel()
  20.   {
  21.     pixel4 a1 = sampleNearest(src, outCoord());
  22.     pixel4 a2 = sampleNearest(src2, outCoord());
  23.     
  24.     pixel4 ss = a1 - a2;
  25.     
  26.     dst = (ss.r>min && ss.g>min && ss.b>min) ? white : black;
  27.   }
  28. }
* This source code was highlighted with Source Code Highlighter.


Пишем программу


Чтение кода не должен вызвать затруднений, только поясню некоторые вещи.

bmp1 — отпечаток картинки видео самого нового кадра
bmp2 — отпечаток bmp1, то есть предыдущий кадр от самого нового
bmp3 — результирующая картинка после применения фильтра PixelBender'а
cmf — фильтр который вычитает из всех пикселей картинки альфу по 10
out — картинка которую мы видим, на нее каждый кадр накладывается bmp3, а также фильтр cmf и blur
  1. package {
  2.   
  3.   import flash.display.Bitmap;
  4.   import flash.display.BitmapData;
  5.   import flash.display.Shader;
  6.   import flash.display.ShaderJob;
  7.   import flash.display.Sprite;
  8.   import flash.events.Event;
  9.   import flash.filters.BlurFilter;
  10.   import flash.filters.ColorMatrixFilter;
  11.   import flash.geom.Point;
  12.   import flash.media.Video;
  13.   import flash.net.NetConnection;
  14.   import flash.net.NetStream;
  15.   import flash.utils.ByteArray;
  16.   
  17.   [SWF(width=376, height=160, backgroundColor=0x0)]
  18.   
  19.   public class SubstractTv extends Sprite {
  20.     
  21.     [Embed(source="../assets/kutu.pbj", mimeType="application/octet-stream")]
  22.     private var pbj:Class;
  23.     
  24.     private var wid:uint = stage.stageWidth;
  25.     private var hei:uint = stage.stageHeight;
  26.     
  27.     private var video:Video;
  28.     private var nc:NetConnection;
  29.     private var ns:NetStream;
  30.     
  31.     private var bmp1:BitmapData;
  32.     private var bmp2:BitmapData;
  33.     private var bmp3:BitmapData;
  34.     private var out:BitmapData;
  35.     private var bmp:Bitmap;
  36.     
  37.     private var shader:Shader;
  38.     private var shaderJob:ShaderJob;
  39.     
  40.     private var blur:BlurFilter;
  41.     private var cmf:ColorMatrixFilter;
  42.     
  43.     public function SubstractTv() {
  44.       nc = new NetConnection();
  45.       nc.connect(null);
  46.       ns = new NetStream(nc);
  47.       ns.client = new Object();
  48.       ns.play("video.f4v");
  49.       
  50.       video = new Video(wid, hei);
  51.       video.attachNetStream(ns);
  52.       
  53.       bmp1 = new BitmapData(wid, hei, true);
  54.       bmp2 = bmp1.clone();
  55.       bmp3 = bmp1.clone();
  56.       out = bmp1.clone();
  57.       bmp = new Bitmap(out, "auto", true);
  58.       addChild(bmp);
  59.       
  60.       shader = new Shader(new pbj() as ByteArray);
  61.       shader.data.src.input = bmp1;
  62.       shader.data.src2.input = bmp2;
  63.       createShaderJob();
  64.       
  65.       addEventListener(Event.ENTER_FRAME, onEnterFrame);
  66.       
  67.       blur = new BlurFilter(3, 3, 3);
  68.       cmf = new ColorMatrixFilter([  1, 0, 0, 0, 0,
  69.                       0, 1, 0, 0, 0,
  70.                       0, 0, 1, 0, 0,
  71.                       0, 0, 0, 1, -10]);
  72.     }
  73.     
  74.     private function onEnterFrame(e:Event):void {
  75.       if (shaderJob.progress != 1) return;
  76.       
  77.       bmp2.draw(bmp1);
  78.       try {
  79.         bmp1.draw(video);
  80.       } catch(e:Error) {}
  81.       
  82.       createShaderJob();
  83.       
  84.       out.applyFilter(out, out.rect, new Point(), blur);
  85.       out.applyFilter(out, out.rect, new Point(), cmf);
  86.       out.draw(bmp3);
  87.     }
  88.     
  89.     private function createShaderJob():void {
  90.       shaderJob = new ShaderJob(shader, bmp3, wid, hei);
  91.       shaderJob.start();
  92.     }
  93.     
  94.   }
  95. }
* This source code was highlighted with Source Code Highlighter.
Теги:
Хабы:
Всего голосов 4: ↑3 и ↓1+2
Комментарии9

Публикации

Ближайшие события