Previous Page
Next Page

Recipe 8.13. Applying a Filter to a Bitmap

Problem

You want to apply a filter to a BitmapData.

Solution

Use the applyFilter( ) method of the BitmapData class, or add a filter to the filters array of the enclosing Bitmap.

Discussion

As mentioned, there are two methods of applying a filter to a bitmap. The first method is to use the applyFilter( ) method directly on the BitmapData itself. Like some of the other BitmapData methods, this method is applied to one BitmapData, which is the destination bitmap, and it can take another BitmapData as a source bitmap:

destBmp.applyFilter(srcBmp, sourceRect, destPoint, filter);

  • The srcBmp is the bitmap file you want to apply the filter to.

  • The sourceRect is the specific rectangular area from the source bitmap that you want to apply the filter to.

  • The destPoint parameter specifies the upper lefthand point from which the pixels will be affected in the destination bitmap.

  • The filter, of course, is an instance of the BitmapFilter that you want to apply.

You can, of course, apply a filter using the same bitmap as both source and destination. Doing so is considered "destructive," not because it's a bad thing but because it permanently changes the bitmap.


The values of each pixel are calculated based on the original content and the filter parameters, and these values overwrite the original pixel data. This is useful in a couple of instances:

  • If you are sure you will never need to change either the bitmap's content or the filter itself.

  • When you have multiple or repeated applications of a filter.

For example, the following code sets 100 random pixels near the mouse position to white and then applies a default blur filter. This is repeated on each frame, so the longer you leave the mouse at one point, the brighter it gets. However, as you move it around, the blur is repeatedly applied to those white pixels, eventually fading them out. The result is a glowing trail.

package {
    import flash.display.Sprite;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.filters.BlurFilter;
    import flash.events.Event;
    import flash.geom.Point;

    public class FilteredBitmap extends Sprite {
        private var _bitmap:BitmapData;
        private var _image:Bitmap;
        private var _blurFilter:BlurFilter;
        
        public function FilteredBitmap(  ) {
            _bitmap = new BitmapData(stage.stageWidth, stage.stageHeight,
                                 false, 0xff000000);
            _image = new Bitmap(_bitmap);
            addChild(_image);
            _blurFilter = new BlurFilter(  );
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        public function onEnterFrame(event:Event):void {
            for(var i:int = 0; i < 100; i++) {
                _bitmap.setPixel(mouseX + Math.random(  ) * 20 - 10,
                             mouseY + Math.random(  ) * 20 - 10,
                             0xffffffff);
            }
            _bitmap.applyFilter(_bitmap, _bitmap.rect, new Point(  ), _blurFilter);
        }
    }
}

As you can see, the destructive method can be quite creative. Contrast that to a nondestructive method that uses two different bitmaps. One is the source bitmap and the other is the destination. The method applies the filter to the bitmap data in the source bitmap, and places the result in the destination bitmap. It is nondestructive because the filter never alters the original pixels in the source bitmap.

package {
    import flash.display.Sprite;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.filters.BlurFilter;
    import flash.events.Event;
    import flash.geom.Point;

    public class FilteredBitmap2 extends Sprite {
        private var _bitmap:BitmapData;
        private var _bitmap2:BitmapData;
        private var _image:Bitmap;
        private var _blurFilter:BlurFilter;

        public function FilteredBitmap2(  ) {
            _bitmap = new BitmapData(stage.stageWidth, stage.stageHeight,
                                  false, 0xff000000);
            _bitmap2 = new BitmapData(stage.stageWidth, stage.stageHeight,
                                   false, 0xff000000);
            _image = new Bitmap(_bitmap);
            addChild(_image);
            _blurFilter = new BlurFilter(  );
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        public function onEnterFrame(event:Event):void {
            for(var i:int = 0; i < 100; i++) {
            _bitmap2.setPixel(mouseX + Math.random(  ) * 20 - 10,
                           mouseY + Math.random(  ) * 20 - 10,
                          0xffffffff);
            }
            _bitmap.applyFilter(_bitmap2, _bitmap.rect, new Point(  ), _blurFilter);
        }
    }
}

The other method of applying a filter to a bitmap is to add it to the filters property of the Bitmap that holds a BitmapData. This is another nondestructive method of applying a filter, as the pixel data in the BitmapData is not touched. The filter is only applied to the Bitmap that wraps the BitmapData. The following code shows this method in action.

package {
    import flash.display.Sprite;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.filters.BlurFilter;
    import flash.events.Event;

    public class FilteredBitmap3 extends Sprite {
        private var _bitmap:BitmapData;
        private var _image:Bitmap;
        
        public function FilteredBitmap3(  ) {
            _bitmap = new BitmapData(stage.stageWidth, stage.stageHeight,
                                  false, 0xff000000);
            _image = new Bitmap(_bitmap);
            addChild(_image);
            _image.filters = [new BlurFilter(  )];
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        public function onEnterFrame(event:Event):void {
            for(var i:int = 0; i < 100; i++) {
                _bitmap.setPixel(mouseX + Math.random(  ) * 20 - 10,
                              mouseY + Math.random(  ) * 20 - 10,
                              0xffffffff);
            }
        }
    }
}

Here you can see that the filter is applied only the one time. The drawn pixels are slightly blurred, but they don't continuously blur until they fade out. If at some point you deleted the filter from the Bitmap, you would see that the white pixels are still perfectly sharp, as the blur was only applied to the container, not the actual bitmap data.

See Also

Recipes 8.12, 8.14, and 8.15 for other ways to manipulate the content in a bitmap.


Previous Page
Next Page
Converted from CHM to HTML with chm2web Pro 2.85 (unicode)