Showcase and discover digital art at yex

Follow Design Stacks

Subscribe to our free newsletter to get all our latest tutorials and articles delivered directly to your inbox!

Image API in Flash 8: Displaying Images

Displaying Images

An instance of the BitmapData class is stored in memory and never seen until you decide it is time for it to make an appearance, at which point you need to attach the bitmap to the Stage so it can be rendered. You can display an instance of the BitmapData object inside any movie clip using the new MovieClip.attachBitmap method:

import flash.display.BitmapData

myBitmap = new BitmapData(100,100,false,0xFFFFCC00);
this.createEmptyMovieClip("holder_mc",1)
holder_mc.attachBitmap(myBitmap,1);

It is a good idea to create an empty movie clip whose sole purpose is to display a bitmap, because there is no method to remove a bitmap after you have attached it to a movie clip. Putting the bitmap inside its own movie clip means you can remove the bitmap at a later stage by removing the movie clip:

holder_mc.removeMovieClip() 

When you attach a bitmap to a movie clip, any changes you make to that movie clip will be updated automatically; you don’t have to re-attach a bitmap every time you change it.

Snapshots

One of the great features of the BitmapData class is the ability to take a snapshot of the visual state of anything that has an instance name as a bitmap, such as movie clips, video objects, and text fields. This also makes it possible to create a freeze-frame of streaming video, webcams, or a movie clip.

To create a bitmap from a movie clip or other instances on the Stage you use the BitmapData.draw() method. By default, this method draws a bitmap representation of an object’s current visual state with no transformations applied to the bitmap object. This means that if you take a snapshot of a video object that is currently showing the video feed from a webcam, and that video object is rotated, the bitmap representation that is created will not be rotated. I’ll discuss this in more detail below, in the section “Snapshot with Transformation.”

For now, concentrate on the absolute coolness of the BitmapData.draw() method. In its simplest form, the method simply uses the vector renderer to draw a bitmap representation of the specified object. This method can also be used to apply blend modes to a bitmap or to mathematically transform the color values of the bitmap using the ColorTransform class. For example, suppose you have a movie clip instance on the Stage called animation_mc and inside that movie clip is some vector animation. At any point during the animation you can take a snapshot of the current visual state of the animation as a bitmap like this:

import flash.display.BitmapData

myBitmap = new BitmapData(
animation_mc._width,animation_mc._height,true,0x00FFFFFF)
myBitmap.draw(animation_mc)

Transformation Matrixes

In Flash Player 8 there is a new Matrix ActionScript class that takes the hard work out of creating transformation matrixes. A transformation matrix is a 3 x 3 grid of numbers that is used to map points from one coordinate space to another. Using just one transformation matrix, you can skew, rotate, scale, and move a bitmap or movie clip all at the same time. Discussing the Matrix class in detail is beyond the scope of this article. Instead, I will introduce you to a few of the methods of the Matrix class that you might end up using quite often, particularly when working with the second parameter of the BitmapData.draw() method.

To create a transformation matrix, start by importing the fully qualified class path so you don’t have to type it over and over again. You can find the Matrix class in the flash.geom package:

import flash.geom.Matrix 

You can then create an instance of the Matrix class using this code:

m = new Matrix() 

This creates a default identity matrix. When applied to an object, an identity matrix does not change the scale, rotation, skew, or position of the object.

After you have created an identity matrix, you can use the various methods of the Matrix class to modify the internal properties of the object and apply various transformations to an object.

You can use the Matrix.scale() method to modify the matrix so that when it is applied to an object, it will scale the object. For example, to create a transformation matrix that will scale an object to twice its size, use this code:

import flash.geom.Matrix 
m = new Matrix()
m.scale(2,2)

If you also want to rotate the object when you apply the transformation matrix, then you can use the Matrix.rotate() method. This method accepts the angle, in radians, at which you want the object to be rotated. To convert an angle from degrees into radians use the following simple math:

radians=(degrees/180)*Math.PI 

The following code modifies the transformation matrix; when you apply the code to an object, the code rotates the object 45 degrees:

m.rotate((45/180) Math.PI) 
// 45 degrees in radians

To move an object when you apply the transformation matrix, you can modify the matrix using the Matrix.translate() method such that when you apply the transformation matrix to an object it will be displaced by the specified offsets:

m.translate(100,100) 
//displace the object by 100 pixels on the x and y axis

You now have a transformation matrix that, when applied to an object, scales the object to twice its size, rotates the object 45 degrees, and displaces the object by 100 pixels on the x and y axis.

Snapshot with Transformation

I mentioned previously that the BitmapData.draw() method accepts a transformation matrix as its second parameter. This enables you to take a snapshot of an object on the Stage and transform it when a bitmap representation of it is drawn.

When you take a snapshot of a movie clip, it is drawn without any transformations applied to it by default, which means that if you rotate a movie clip on the Stage and then scale it and take a snapshot of it, the bitmap representation that is created will not be rotated or scaled. However, if you specify a transformation matrix as the second parameter to the draw() method when you take a snapshot, then you can apply these same transformations to the bitmap.

When you scale, rotate, or move a movie clip on the Stage either using ActionScript or in the authoring environment, internally, Flash Player uses a transformation matrix to display the movie clip with the correct transformations. In Flash Player 8 you can access this low-level transformation matrix using the Movieclip.transform.matrix property. This property returns an instance of the Matrix class that is pre-populated with the correct transformation values. You can use this property to determine which transformations have been applied to a movie clip. You can also make one movie clip have the same transformations as another movie clip using the following code:

Movieclip1.transform.matrix=movieclip2.transform.matrix 

The following code creates a movie clip that contains a square and then uses scales and rotates the movie clip using ActionScript:

import flash.display.BitmapData

this.createEmptyMovieClip("square_mc",1)

//draw a yellow square inside of the movie clip
//using the drawing api

with(square_mc)
{
beginFill(0xFFCC00)
lineStyle(1,0x000000)
lineTo(0,100)
lineTo(100,100)
lineTo(100,0)
lineTo(0,0)
endFill()
}

//rotate the square
square_mc._rotation=45

//scale the square to twice its size
square_mc._xscale=square_mc._yscale=200

If you were to take a snapshot of the above movie clip, the square would not be rotated or scaled in the bitmap unless you specify a transformation matrix. If you want the square movie clip to appear exactly as it does on the Stage when it is drawn as the bitmap object, you should specify the movie clip’s transformation matrix as the second parameter to the draw() method:

//create a transparent bitmap 
//that is the same size as the movie clip
myBitmap =new BitmapData(
square_mc._width,square_mc._height,true,0x00FFFFFF)

//draw it exactly as it appears on the Stage
myBitmap.draw(square_mc,square_mc.transform.matrix)

If you don’t want the movie clip to appear as it does on the Stage—for example you may want the bitmap representation of the movie clip to be half the size of the movie clip as it appears on the Stage—you can access the movie clip’s transformation matrix and modify it such that when it is applied to the bitmap, the necessary transformations are applied:

//create a transparent bitmap 
//that is half the size of the movie clip on the Stage
myBitmap = new BitmapData(
square_mc._width/2,square_mc._height/2,true,0x00FFFFFF)
//get the movie clips transformation matrix
m=square_mc.transform.matrix

/*
Modify the movie clips transformation matrix
so that when it is applied to the bitmap
it will be drawn at half its size
*/

m.scale(0.5,0.5)
//snapshot the movie clip at half its size
myBitmap.draw(square_mc,m)

Comments