topical media & game development
#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.