In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

VTR Filter for web camera

VTR調変換.
走査線, ゴースト (二重写り), ガンマ補正.
scanning lines, ghost and gamma correction.

see also:http://rest-term.com/archives/2827/
Get Adobe Flash player
by wellflat 24 Oct 2010
/**
 * Copyright wellflat ( http://wonderfl.net/user/wellflat )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/nEqt
 */

package {
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.display.Sprite;
  import flash.events.ActivityEvent;
  import flash.media.Camera;

  public class Main extends Sprite {
    private var camera:Camera;
    private var screen:Bitmap;
    private var vtr:VTR;

    public function Main() {
      Wonderfl.capture_delay(10);
      stage.scaleMode = "noScale";
      camera = Camera.getCamera();
      if(camera) {
        camera.setMode(320, 240, 30);
        screen = new Bitmap(new BitmapData(camera.width, camera.height, false));
        camera.addEventListener(ActivityEvent.ACTIVITY, onActivity);
        vtr = new VTR(screen);
        vtr.attachCamera(camera);
        vtr.setCondition(4, 4, 4, 2.0);
        addChild(screen);
      }else {
        throw new Error("required camera");
      }
    }
    private function onActivity(e:ActivityEvent):void {
      removeEventListener(ActivityEvent.ACTIVITY, arguments.callee);
      vtr.start();
    }
  }
}

  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.events.Event;
  import flash.media.Video;

  class VTR extends Video {
    private var _contrast:int;
    private var _thick:int;
    private var _ghost:int;
    private var gtbl:Vector.<uint>;
    private var frame:BitmapData;
    
    public function VTR(screen:Bitmap) {
      super(screen.width, screen.height);
      frame = screen.bitmapData;
      gtbl = new Vector.<uint>(256, true);
    }
    public function setCondition(contrast:int, ghost:int, thick:int,
                              gamma:Number):void {
      _contrast = contrast;
      _ghost = ghost;
      _thick = thick; // require 2^x
      for(var i:int=0; i<256; i++) {  // create table for gamma correction.
        gtbl[i] = Math.pow(i/255.0, gamma)*255.0;
      }
    }
    public function start():void { // start apply effect (onEnterFrame).
      addEventListener(Event.ENTER_FRAME, apply, false, 0, true);
    }
    /** main algorithm
        add scannning lines, ghost and gamma collection. **/
    private function apply(e:Event):void {
      frame.draw(super);
      frame.lock();
      var data:Vector.<uint> = frame.getVector(frame.rect);
      var w:int = frame.width, h:int = frame.height;
      var r:uint = 0, g:uint = 0, b:uint = 0;
      var i:int = 0, j:int = 0, step:int = w;
      var f:int = 1;
      var len:int = data.length;
      for(var y:int = 0; y < h; y++, step += w) {
        f = (y & _thick - 1) << 1 < _thick ? 1 : 0;
        if(step + _ghost >= len) break;
        for(j = i + _ghost; i < step; i++, j++) {
          r = ((data[i] >> 16) & 0xff) + ((data[j] >> 16) & 0xff) >> 1;
          g = ((data[i] >> 8) & 0xff) + ((data[j] >> 16) & 0xff) >> 1;
          b = (data[i] & 0xff) + (data[j] & 0xff) >> 1;
          if(f && (r = g = b += _contrast) > 0xff) {
            r = g = b = 0xff;
          }
          data[i] = gtbl[r] << 16 | gtbl[g] << 8 | gtbl[b];
        }
      }
      frame.setVector(frame.rect, data);
      frame.unlock();
    }
  }