Introducing the Bitmap API


Flash Player 8 has a new class called BitmapData that you can use to work with bitmap data in many ways that were not possible with previous versions of Flash Player. For example, in this lesson you'll build an application that applies flood fills to a bitmap in order to make a coloring page program. You can also use BitmapData objects to get and set the values of each pixel, which you'll use in order to add a flexible color palette to the coloring page program.

The BitmapData class comprises what is often called the Bitmap API. The Bitmap API has quite an array of functionality. In this lesson we'll look at some of the more common features as well as how to get started.

The BitmapData class is in the flash.display package. That means that either you have to use the fully qualified class name when referencing the class or you need to import the class before using it. Using an import statement is often simpler and clearer than using the fully qualified class name every time you reference the class. Throughout the rest of this lesson we'll assume in every example that the following import statement precedes the example code:

   import flash.display.BitmapData;


Constructing BitmapData Objects

There are two basic ways in which you can construct a BitmapData object. You can use the constructor method in a new statement, or you can use the static loadBitmap() method. Let's take a look at each of the two options, how they work, and when you'd use each option.

Tip

In addition to the constructor method and the loadBitmap() method, you can also construct a new BitmapData object that is a duplicate of an existing object using the clone() method.


The BitmapData constructor method requires, at minimum, two parameters specifying the width and height of the new BitmapData object. The following constructs a new object that is 200 pixels wide and 400 pixels high:

   var exampleBmp:BitmapData = new BitmapData(200, 400);


The constructor accepts two additional parameters that specify whether the object supports transparency and what background color to use. By default, BitmapData objects support transparency, but the background is set to 0xFFFFFFFF, which is a 32-bit integer in the form of 0xAARRGGBB specifying a white, fully opaque background color. So although the object supports transparency, it has a white background. If you want to make the object truly transparent, set the background color to 0x00000000.

   var exampleBmp.BitmapData = new BitmapData(200, 400, true, 0x00000000);


Use the BitmapData constructor when you want to build a new object for the purposes of adding content programmatically (adding noise, rectangular fills, copying content from movie clips, and so on). If you want to make a BitmapData object from a bitmap symbol in the library, however, you can simply use the static loadBitmap() method of the BitmapData class.

The loadBitmap() method requires just one parametera string specifying the linkage identifier of the bitmap symbol from which you want to make the new object. That means that you must set the bitmap symbol to Export For ActionScript and assign it a linkage identifier in the symbol's linkage properties. You can accomplish that much as you would for a movie clip symbol. Select the bitmap symbol in the library, open either the library menu or the symbol's context menu, and select Linkage. Then click the Export For ActionScript option and specify a linkage identifier. The following code makes a new BitmapData object from a bitmap symbol exported with a linkage identifier of Example:

  var exampleBmp:BitmapData = BitmapData.loadBitmap("Example");


Displaying BitmapData Content

BitmapData objects aren't displayed by default. If you want to display the content from a BitmapData object, you have to use a movie clip object. You can call the attachBitmap() method from any movie clip object to add the content from a BitmapData within the movie clip. The method requires, at minimum, two parameters specifying the BitmapData object and the depth at which you want to attach the content within the movie clip. The following adds the content from exampleBmp to a movie clip called exampleClip:

   exampleClip.attachBitmap(exampleBmp, exampleClip.getNextHighestDepth());


You can specify two additional parameters that determine how the content snaps to pixels and whether smoothing is applied. By default, bitmap content snaps to whole pixel values unless the content is scaled or rotated. That means that if a movie clip containing bitmap content is placed so that its x coordinate is at 40.1 on the Stage, the bitmap content will snap to 40. The default value for the snapping parameter is the string auto. You can also specify always if you want the bitmap content to snap to whole pixels regardless of whether it's scaled or rotated and you can specify never if you don't want the content to snap to pixels. The smoothing setting is false by default. That means that as the bitmap is scaled, it can appear pixelated. If smoothing is set to true, the pixelated appearance of scaled bitmap content is smoothed. The following code attaches bitmap content to exampleClip, specifying that it ought to always snap to whole pixels and that smoothing is enabled.

   exampleClip.attachBitmap(exampleBmp, exampleClip.getNextHighestDepth(), ¬   "always", true);


Building a Coloring Page Program

In this next task you'll start building a coloring page program. The program displays line art to the user and it enables the user to select a color from a color palette and apply the color to a section of the page. To start, however, you'll simply attach the bitmaps from the library.

1.

Open coloringPage1.fla from the Lesson09/Start directory.

The Flash document contains all the assets you'll need to get started with the program. You'll notice that there's nothing on the Stage. However, if you look in the library you'll see that there are several symbols that you'll be able to attach programmatically.

2.

Set the ColorPalette, ColorSelector, and ColoringPage symbols to export for ActionScript. Use the default linkage identifiers of ColorPalette, ColorSelector, and ColoringPage.

You'll attach each of the symbols programmaticallyColorPalette using attachMovie(), and ColorSelector and ColoringPage using loadBitmap().

3.

Select the keyframe on the Actions layer of the main Timeline and open the Actions panel by pressing F9. Add the following import statements to the script pane:

  import flash.display.BitmapData;   import flash.filters.DropShadowFilter;


The program uses BitmapData for most of the functionality, so you'll want to import the class to simplify working with it. In addition, you'll add a drop shadow to the color palette, so import the DropShadowFilter class.

4.

Load the bitmaps using the following code:

  var coloringPageBmp:BitmapData = ¬     BitmapData.loadBitmap("ColoringPage");   var colorSelectorBmp:BitmapData = ¬     BitmapData.loadBitmap("ColorSelector");


The preceding code loads the ColoringPage and ColorSelector bitmaps into two new BitmapData objects. Remember, the bitmaps don't get displayed by default. For that you'll have to add the bitmap content to movie clips.

5.

Add the coloring page bitmap content to a movie clip using the following code:

  var coloringPageClip:MovieClip = ¬     this.createEmptyMovieClip("coloringPageClip", ¬     this.getNextHighestDepth());   coloringPageClip.attachBitmap(coloringPageBmp, ¬     coloringPageClip.getNextHighestDepth());


The preceding code makes a new movie clip object called coloringPageClip. It then attaches the bitmap content from coloringPageBmp to the new movie clip so that it gets displayed. If you were to test the movie at this point you'd see the coloring page.

6.

Add the color palette, and attach the color selector to it using the following code:

  var colorPaletteClip:MovieClip = this.attachMovie("ColorPalette", ¬     "colorPaletteClip", this.getNextHighestDepth());   colorPaletteClip.createEmptyMovieClip("selectorClip", ¬     colorPaletteClip.getNextHighestDepth());   colorPaletteClip.selectorClip.attachBitmap(colorSelectorBmp, ¬     colorPaletteClip.selectorClip.getNextHighestDepth());   colorPaletteClip.selectorClip._y = 40;   colorPaletteClip.selectorClip._x = colorPaletteClip._width / 2 - ¬     colorPaletteClip.selectorClip._width / 2;   colorPaletteClip.filters = [new DropShadowFilter(10, 45, 0x000000, 50, 10, 10)];


The preceding code attaches an instance of the ColorPalette movie clip symbol and calls it colorPaletteClip. It then creates a new movie clip within colorPaletteClip and it attaches the bitmap content from colorSelectorBmp to the nested movie clip. The nested movie clip is necessary to center the bitmap content within the color palette. When attaching bitmap content to a movie clip, there is no option to translate the content. Because you want the color selector to appear centered within the color palette you need to add it to a nested movie clip which can be moved.

The color selector movie clip is placed just below the palette title bar, and it is centered horizontally. Then you add a drop shadow to the entire palette.

7.

Test the movie.

When you test the movie, you'll see the coloring page as well as the color palette with the nested color selector.

Applying Flood Fills

Flood fills are fills in which Flash Player applies a solid color to a contiguous region within a bitmap. A region is determined by specifying a pixel, and Flash Player then selects that pixel and every adjacent pixel with the same color value. You can apply flood fills to BitmapData objects using the floodFill() method. The method requires three parameters: the x coordinate, the y coordinate, and the fill color in the form of 0xRRGGBB. For example, the following code applies a red fill to the contiguous region specified by the point 100,100 within exampleBmp.

  exampleBmp.floodFill(100, 100, 0xFF0000);


Working with Pixels

You can get and set pixel values within BitmapData objects using the getPixel(), setPixel(), getPixel32(), and setPixel32() methods. The getPixel() and setPixel() methods use 24-bit integer values in the form of 0xRRGGBB. The getPixel32() and setPixel32() methods use 32-bit integer values in the form of 0xAARRGGBB. Otherwise, the two sets of methods work identically.

The getPixel() and getPixel32() methods require two parameters, specifying the x and y coordinates of the pixel within the bitmap content for which you want to retrieve the pixel value. The following code retrieves the 24-bit color value for the pixel at 100,400 within exampleBmp:

  var pixelValue:Number = exampleBmp.getPixel(100, 400);


The setPixel() and setPixel32() methods require three parameters, specifying the x coordinate, the y coordinate, and the new pixel value. The following code sets the pixel at 100, 400 to red:

  exampleBmp.setPixel(100, 400, 0xFF0000);


Continuing the Coloring Page Program

In this next task you'll add the coloring functionality to the coloring page program.

1.

Open the Flash document completed from the previous task. Optionally, open coloringPage2.fla from Lesson09/Completed.

The Flash document contains all the necessary elements to complete the task.

2.

Select the keyframe on the Actions layer of the main Timeline and open the Actions panel by pressing F9. Then, following the existing code, declare a new variable called selectedColor as follows:

  var selectedColor:Number;


You'll use the selectedColor variable to store the color value that the user selects from the color selector.

3.

Add an onPress() event handler method to colorPaletteClip.selectorClip so that it gets the pixel value from the color selector where the user clicks and assigns it to selectedColor.

   colorPaletteClip.selectorClip.onPress = function():Void {      selectedColor = colorSelectorBmp.getPixel(colorPaletteClip._xmouse - ¬        colorPaletteClip.selectorClip._x, colorPaletteClip._ymouse - ¬        colorPaletteClip.selectorClip._y);    };


The preceding code is fairly straightforward except that the x and y coordinates specified for getPixel() might not seem immediately clear. The x and y coordinates that you specify for getPixel() must be relative to the upper-right corner of the bitmap. In the case of the color selector, the x and y coordinates can be determined by the x and y coordinates of the mouse within colorPaletteClip. However, because selectorClip is translated within colorPaletteClip you have to subtract the x and y coordinates of selectorClip from the _xmouse and _ymouse values.

4.

Make the color palette draggable with the following code:

  colorPaletteClip.titleBarClip.onPress = function():Void {     this._parent.startDrag();   };   colorPaletteClip.titleBarClip.onRelease = function():Void {     this._parent.stopDrag();   };   colorPaletteClip.titleBarClip.onReleaseOutside = ¬     colorPaletteClip.titleBarClip.onRelease;


The preceding code makes colorPaletteClip draggable when the user clicks and drags the nested title bar. Making the palette draggable is useful so that the user can move it around in order to color areas of the page that are covered by the palette.

5.

Add the following code so that the selected color is applied as a flood fill to the color page when the user clicks it:

  coloringPageClip.onPress = function():Void {     if(coloringPageBmp.getPixel(_xmouse, _ymouse) == 0x000000) {       return;     }     coloringPageBmp.floodFill(_xmouse, _ymouse, selectedColor);   };


The code initially checks to see whether the pixels at the point at which the user clicks are black. If so, Flash exits the function without applying the flood fill so the user doesn't inadvertently apply a color to the black outlines. Assuming that the user doesn't click the black outlines, the code uses floodFill() to apply the selected color to the coloring page.

6.

Test the movie.

Drag the color palette around, select colors, and apply them to the coloring page.

Copying Content

You can copy content from any BitmapData object, movie clip, or even video object to a BitmapData object using the draw() method. The draw() method requires at minimum two parameters that specify the object from which you want to copy the contents and a transform matrix to use when copying the content. To apply no transforms when copying the content, you can specify a flash.geom.Matrix object with the default values. The following code copies the content from the movie clip imageClip to exampleBmp (the code assumes that the flash.geom.Matrix class has been imported previously):

   exampleBmp.draw(imageClip, new Matrix());


Copying content is particularly useful when you want to make a BitmapData object from an image loaded at runtime, as you'll see in the next task.

Completing the Coloring Page Program

In this task you'll complete the coloring page program so that it loads an image from a file at runtime, which makes it simple to update the line art without having to recompile the SWF file.

1.

Open the Flash document you completed from the previous task. Optionally, open coloringPage3.fla from the Lesson09/Completed directory.

The document contains all the assets necessary to complete the program.

2.

Select the keyframe on the Actions layer and open the Actions panel by pressing F9. Then add the following import statement immediately following the existing import statements:

   import flash.geom.Matrix;


You'll use the Matrix class when copying the loaded image to a BitmapData object, so import it to simplify working with it.

3.

Change the line of code in which you previously constructed the coloringPageBmp object. Declare the variable, but don't construct the object.

   var coloringPageBmp:BitmapData;


In this task you're no longer loading the bitmap from the library. Instead you're loading it from a file at runtime. So you'll use draw() to copy the image to the BitmapData object and you can't construct the object until the image has loaded.

4.

Add the following code to load the image from Tree.gif (add the code just following the declaration of colorPaletteBmp):

    var imageTemporaryClip:MovieClip = ¬       this.createEmptyMovieClip("imageTemporaryClip", ¬       this.getNextHighestDepth());     var imageLoader:MovieClipLoader = new MovieClipLoader();     imageLoader.addListener(this);     imageLoader.loadClip("Tree.gif", imageTemporaryClip);


You'll use a MovieClipLoader object to load the image into an empty movie clip called imageTemporaryClip. Add the main Timeline as a listener object so it gets notified when the image loads.

5.

Delete the line of code in which you previously attached the bitmap contents from coloringPageBmp to coloringPageClip.

Because the bitmap data doesn't exist until the image has loaded, you'll need to defer attaching the bitmap content to the movie clip until that point.

6.

Add an onLoadInit() function that draws the image to the BitmapData object and attaches it to the movie clip.

  function onLoadInit(imageClip:MovieClip):Void {     coloringPageBmp = new BitmapData(imageClip._width, ¬       imageClip._height, false, 0xFFFFFFFF);     coloringPageBmp.draw(imageTemporaryClip, new Matrix());     imageTemporaryClip._visible = false;     coloringPageClip.attachBitmap(coloringPageBmp, 1);   }


The first step in the function is to construct the BitmapData object that has the same dimensions as the loaded image. Set the transparency to false so that even if the background of the loaded image is transparent, the background of the BitmapData object won't be transparent. After the object is constructed, use the draw() method to copy the contents of the movie clip containing the image. At that point, the imageTemporaryClip movie clip object doesn't need to be visible any longer.

7.

Test the movie.

When you test the movie it ought to look and function much as it did in the previous version. However, this time the color page image is loaded from a file at runtime. So for the program to work properly, you'll have to make sure that Tree.gif (from Lesson09/Assets) is located in the same directory as the SWF file.




Macromedia Flash 8 ActionScript Training from the Source
Macromedia Flash 8 ActionScript: Training from the Source
ISBN: 0321336194
EAN: 2147483647
Year: 2007
Pages: 221

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net