topical media & game development

talk show tell print

#graphic-flex-image-effects-04-Flex-FisheyeLensTest.ax

#graphic-flex-image-effects-04-Flex-FisheyeLensTest.ax [swf] [flash] flex


  package {
  
          import flash.display.Bitmap;
          import flash.display.BitmapData;
          import flash.display.BitmapDataChannel;
          import flash.events.MouseEvent;
          import flash.filters.DisplacementMapFilter;
          import flash.filters.DisplacementMapFilterMode;
          import flash.geom.Point;
  
          [SWF(width=640, height=480, backgroundColor=0x202020)]
  
          
Demonstrates how DisplacementMapFilter can be used to displace an image in a spherizing/fisheye lens distortion.

  
          public class @ax-graphic-flex-image-effects-04-Flex-FisheyeLensTest extends graphic_flex_image_effects_04_Flex_AbstractImageLoader {
  
                  private static const DIAMETER:uint = 200;
  
                  private var _bitmapData:BitmapData;
                  private var _lens:BitmapData;
                  private var _lensBitmap:Bitmap;
  
                  
Constructor. Passes path of image to load to super class.

  
                  public function @ax-graphic-flex-image-effects-04-Flex-FisheyeLensTest() {
                          super("graphic-flex-image-effects-04-assets-checkers.jpg");
                  }
  
                  
Run after the image loads in super class. This creates the displacement map to be used on the loaded image, uses this data in a new bitmap that is moved about the stage to show the map in its current position, and sets up listeners for the mouse on the stage.

  
                  override protected function runPostImageLoad():void {
                          _bitmapData = _loadedBitmap.bitmapData.clone();
                          // creates the data that will be used as the displacement map
                          _lens = createLens(DIAMETER);
                          // bitmap just used to help visualize the distortion, but is not needed for the effect
                          _lensBitmap = new Bitmap(_lens);
                          // made invisible initially, but can be made visible by mouse click
                          _lensBitmap.visible = false;
                          // apply initial distortion
                          applyLens();
                          addChild(_loadedBitmap);
                          addChild(_lensBitmap);
                          stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
                          stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
                          stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
                  }
  
                  
Creates a displacement map for the fisheye lens effect.
parameter: diameter The diameter of the lens to create.
parameter: amount The amount of distortion the map should enable.
returns: The map needed for the displacement.

  
                  private function createLens(diameter:uint, amount:Number=0.8):BitmapData {
                          // by default, map is filled with medium gray, which results in no displacement
                          var lens:BitmapData = new BitmapData(diameter, diameter, false, 0xFF808080);
                          // values are the same, but kept separate just for clarity
                          var center:Number = diameter/2;
                          var radius:Number = center;
                          // run through full height of map
                          for (var y:uint=0; y < diameter; ++y) {
                                  // current y coordinate in relation to the center of the map
                                  var ycoord:int = y - center;
                                  // run through full width of map
                                  for (var x:uint = 0; x < diameter; ++x) {
                                          // current x coordinate in relation to the center of the map
                                          var xcoord:int = x - center;
                                          // the distance from the current coordinates to the map center
                                          var distance:Number = Math.sqrt(xcoord*xcoord + ycoord*ycoord);
                                          // only if we are within the radius of the lens do we need to recolor
                                          if (distance < radius) {
                                                  // a number between 0 and 1 based on the distance from center and the amount of distortion
                                                  var t:Number = Math.pow(Math.sin(Math.PI/2 * distance/radius), amount);
                                                  // the amount of distortion on each axis determines the amount to recolor
                                                  // the pixel at the current coordinate, using the blue channel for horizontal distortion
                                                  // and the green channel for vertical distortion
                                                  var dx:Number = xcoord * (t - 1)/diameter;
                                                  var dy:Number = ycoord * (t - 1)/diameter;
                                                  var blue:uint = 0x80 + dx * 0xFF;
                                                  var green:uint = 0x80 + dy * 0xFF;
                                                  lens.setPixel(x, y, green << 8 | blue);
                                          }
                                  }  
                          }
                          return lens;
                  }
  
                  
Reapplies the displacement map on the image based on the current mouse position.

  
                  private function applyLens():void {
                          // the point of displacement is determined by the mouse position
                          var displacementMapFilter:DisplacementMapFilter = new DisplacementMapFilter(
                                  _lens,
                                  new Point(stage.mouseX-DIAMETER/2, stage.mouseY-DIAMETER/2),
                                  BitmapDataChannel.BLUE,
                                  BitmapDataChannel.GREEN,
                                  DIAMETER,
                                  DIAMETER,
                                  DisplacementMapFilterMode.CLAMP
                          );
                          // displacement is applied
                          _loadedBitmap.bitmapData.applyFilter(
                                  _bitmapData,
                                  _bitmapData.rect,
                                  new Point(),
                                  displacementMapFilter
                          );
                  }
  
                  
Handler for when the mouse is moved about the stage. This moves the displacement map image and reapplies the displacement.
parameter: event Event dispatched by stage.

  
                  private function onStageMouseMove(event:MouseEvent):void {
                          _lensBitmap.x = stage.mouseX - DIAMETER/2;
                          _lensBitmap.y = stage.mouseY - DIAMETER/2;
                          applyLens();
                          event.updateAfterEvent();
                  }
  
                  
Handler for when the mouse is pressed on the stage. This makes visible the displacement map.
parameter: event Event dispatched by stage.

  
                  private function onStageMouseDown(event:MouseEvent):void {
                          _lensBitmap.visible = true;
                  }
  
                  
Handler for when the mouse is released on the stage. This removes visibility of the displacement map.
parameter: event Event dispatched by stage.

  
                  private function onStageMouseUp(event:MouseEvent):void {
                          _lensBitmap.visible = false;
                  }
  
          }
  
  }
  


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.