Recipe 8.14.
Dissolving Between Two Bitmaps
Problem
You want
to fade between one bitmap and another.
Solution
Use the
pixelDissolve( ) method of the BitmapData class.
Discussion
Like many of the other BitmapData
methods, pixelDissolve( ) uses a source and destination
bitmap. Each time it is called, it copies a specified number of
random pixels from the source bitmap to the destination. To
complete a full dissolve, call this method repeatedly, either in an
enterFrame handler or
a timer-based function. See Recipe
11.1 for information on timer-based animation.
The first time the pixelDissolve( )
method is called, you pass it a random number to use as a seed for
the first round of pixel copying. It returns a number that you
should keep track of and use as the seed for the next
iteration.
Here is the syntax for the method:
seed = srcBmp.pixelDissolve(destBmp, sourceRect, destPoint,
seed, numPixels, fillColor);
-
The sourceRect and
destPoint
parameters work the same way they do in other BitmapData
methods that use two bitmaps. The seed is explained
more in Recipe
8.10.
-
The numPixels parameter
determines how many pixels are copied each time the method is
called.
-
The fillColor offers an
easy way of fading a single bitmap to a specified color. If you use
the same BitmapData as source and destination, instead of
copying identical pixels from one to the other (which would have no
visible effect), the chosen pixels are set to the fill color
specified in this parameter. You can ignore this when using two
different bitmaps.
The first example uses two bitmapsone white, one
blackand dissolves between them at 1,000 pixels per frame:
package {
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.geom.Point;
public class Dissolve extends Sprite {
private var _bitmap:BitmapData;
private var _bitmap2:BitmapData;
private var _image:Bitmap;
private var _seed:Number;
private var _pixelCount:int = 0;
public function Dissolve( ) {
_bitmap = new BitmapData(stage.stageWidth,
stage.stageHeight,
false, 0xffffffff);
_bitmap2 = new BitmapData(stage.stageWidth,
stage.stageHeight,
false, 0xff000000);
_image = new Bitmap(_bitmap);
addChild(_image);
_seed = Math.random( ) * 100000;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
public function onEnterFrame(event:Event):void {
_seed = _bitmap.pixelDissolve(_bitmap2,
_bitmap.rect,
new Point( ),
_seed,
1000);
_pixelCount += 1000;
if(_pixelCount > _bitmap.width * _bitmap.height) {
removeEventListener(Event.ENTER_FRAME,
onEnterFrame);
}
}
}
}
An important thing to note here is that the
pixelDissolve( ) method has no way of knowing when it is
done (i.e., when all the pixels have been copied over from one
bitmap to the other). It is up to you to keep a count of the number
of pixels that have been copied and stop copying when this exceeds
the total number of pixels in the image (its width times its
height).
In the following example, the same
BitmapData is used as both source and destination, and a
black fill color is applied:
package {
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.geom.Point;
public class Dissolve2 extends Sprite {
private var _bitmap:BitmapData;
private var _image:Bitmap;
private var _seed:Number;
private var _pixelCount:int = 0;
public function Dissolve2( ) {
_bitmap = new BitmapData(stage.stageWidth,
stage.stageHeight,
false,
0xffffffff);
_image = new Bitmap(_bitmap);
addChild(_image);
_seed = Math.random( ) * 100000;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
public function onEnterFrame(event:Event):void {
_seed = _bitmap.pixelDissolve(_bitmap,
_bitmap.rect,
new Point( ),
_seed,
1000,
0xff000000);
_pixelCount += 1000;
if(_pixelCount > _bitmap.width * _bitmap.height)
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
}
}
}
Pixel dissolves are particularly effective when
done between two photographic images, at a fast rate. If you don't
know what size your images are going to be but you want to keep the
speed constant, you can set numPixels to a percentage of the
size of the image, like so:
var numPixels:Number = _bitmap.width * _bitmap.height / 100;
_seed = _bitmap.pixelDissolve(_bitmap,
_bitmap.rect,
new Point( ),
_seed,
numPixels,
0xff000000);
_pixelCount += numPixels;
This copies 1/100th of the total pixels on each
iteration. At 30 frames per second, this would be (approximately) a
3-second dissolve, regardless of the size of the images.
See Also
Recipes 8.12,
8.13,
and 8.15
for other ways to manipulate
the content in a bitmap.
|