package { import aether.utils.Adjustments; import aether.utils.ImageUtil; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.display.Sprite; import flash.filters.BitmapFilter; import flash.filters.BlurFilter; import flash.filters.DropShadowFilter; import flash.filters.GlowFilter; import flash.geom.Point; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; [SWF(width=800, height=450, backgroundColor=0x000000)] /** * Demonstrates how complex text effects can be created by expanding or contracting textfields * using blurring and levels, then stacking these expanded or contracted fields and applying effects. */ public class graphic_flex_image_effects_09_Flex_StackedText extends Sprite { /** * Constructor. Creates fields, generated multiple bitmaps from each and applies effects. */ public function graphic_flex_image_effects_09_Flex_StackedText() { // make sure Impact is installed var field:TextField = createField("FIELD ONE", new TextFormat("Impact", 100)); // draws field into bitmap data var bitmapData:BitmapData = ImageUtil.getBitmapData(field); // applies filter effect filterImageOne(bitmapData); var bitmap:Bitmap = new Bitmap(bitmapData); bitmap.x = (stage.stageWidth - bitmap.width)/2; bitmap.y = 20; addChild(bitmap); // process is repeated for two more fields field = createField("FIELD TWO", new TextFormat("Impact", 100)); bitmapData = ImageUtil.getBitmapData(field); filterImageTwo(bitmapData); bitmap = new Bitmap(bitmapData); bitmap.x = (stage.stageWidth - bitmap.width)/2; bitmap.y = stage.stageHeight/3 + 20; addChild(bitmap); field = createField("FIELD THREE", new TextFormat("Times New Roman", 100)); bitmapData = ImageUtil.getBitmapData(field); filterImageThree(bitmapData); bitmap = new Bitmap(bitmapData); bitmap.x = (stage.stageWidth - bitmap.width)/2; bitmap.y = stage.stageHeight*2/3 + 20; addChild(bitmap); } /** * Creates a textfield with the specified text and format. * * @param text The text to add to the field. * @param format The text format to apply to the field. * * @return The textfield created. */ private function createField(text:String, format:TextFormat):TextField { var field:TextField = new TextField(); field.defaultTextFormat = format; field.autoSize = TextFieldAutoSize.LEFT; field.text = text; return field; } /** * Applies filters to first field, which is drawn into bitmap data. * * @param source The bitmap data to apply filters to. */ private function filterImageOne(source:BitmapData):void { // creates transparent bitmap data in which beveled image will be drawn var destination:BitmapData = new BitmapData( source.width, source.height, true, 0x00000000 ); addLayer( source, destination, 0xFFFF0000, 10, 90 ); addLayer( source, destination, 0xFF000000, 10, 180 ); addLayer( source, destination, 0xFFFFFFFFF, 10, 200 ); ImageUtil.copyPixels(destination, source); } /** * Applies filters to second field, which is drawn into bitmap data. * * @param source The bitmap data to apply filters to. */ private function filterImageTwo(source:BitmapData):void { // creates transparent bitmap data in which beveled image will be drawn var destination:BitmapData = new BitmapData( source.width, source.height, true, 0x00000000 ); var filters:Vector. = new Vector.(); filters.push(new DropShadowFilter(3, 45, 0xFFFFFF, .8, 5, 5, 1, 1, true, true)); addLayer( source, destination, 0xFF000000, 10, 80, filters ); filters = new Vector.(); filters.push(new DropShadowFilter(3, 45, 0xFFFFFF, .8, 5, 5, 1, 1, true)); filters.push(new DropShadowFilter(3, 225, 0xFFFFFF, .1, 5, 5, 1, 1, true)); addLayer( source, destination, 0xFF121212, 8, 200, filters ); filters = new Vector.(); filters.push(new DropShadowFilter(3, 225, 0x66FFFF, .2, 3, 3, 1, 1, true, true)); addLayer( source, destination, 0xFF000000, 10, 230, filters ); ImageUtil.copyPixels(destination, source); } /** * Applies filters to third field, which is drawn into bitmap data. * * @param source The bitmap data to apply filters to. */ private function filterImageThree(source:BitmapData):void { // creates transparent bitmap data in which beveled image will be drawn var destination:BitmapData = new BitmapData( source.width, source.height, true, 0x00000000 ); var filters:Vector. = new Vector.(); filters.push(new GlowFilter(0x9922FF, 1, 8, 8, 2, 1, false, true)); addLayer( source, destination, 0xFF000000, 8, 90, filters ); filters = new Vector.(); filters.push(new GlowFilter(0xCC55FF, 1, 6, 6, 2, 1, true, true)); addLayer( source, destination, 0xFF000000, 8, 160, filters ); filters = new Vector.(); filters.push(new GlowFilter(0xEEAAFF, 1, 6, 6, 2, 1, true, true)); addLayer( source, destination, 0xFF000000, 10, 230, filters ); ImageUtil.copyPixels(destination, source); } /** * Captures the alpha channel from an image, then blurs it and applies a threshold in order to * thicken or thin opaque pixels of image. The resulting alpha channel is copied into bitmap data * with a specified fill and a bevel is applied. * * @param source The source bitmap data image. * @param destination The image in which the effect will be drawn. * @param fillColor The color of the resulting image. * @param blurAmoun The amount to blur the image before the threshold is applied. * @param threshold The threshold to apply, which will determine how thick or thin the image will be. * @param filters A vector of filters to apply to the resulting image. */ private function addLayer( source:BitmapData, destination:BitmapData, fillColor:uint, blurAmount:Number, threshold:uint, filters:Vector.=null ):void { // create grayscale image from alpha channel of source var alpha:BitmapData = ImageUtil.getChannelData(source, BitmapDataChannel.ALPHA); // blur the grayscale image ImageUtil.applyFilter(alpha, new BlurFilter(blurAmount, blurAmount)); // apply a threshold to the blurred image Adjustments.setLevels(alpha, threshold-20, threshold, threshold+20); // blur the threshold result to soften pixelation ImageUtil.applyFilter(alpha, new BlurFilter(1.5, 1.5)); // create a new image that is a solid color var bevel:BitmapData = source.clone(); bevel.fillRect(bevel.rect, fillColor); // copy the altered alpha channel into solid color bitmap data bevel.copyChannel( alpha, alpha.rect, new Point(), BitmapDataChannel.RED, BitmapDataChannel.ALPHA ); // apply filters for each (var filter:BitmapFilter in filters) { ImageUtil.applyFilter(bevel, filter); } // draw beveled image into destination bitmap data destination.draw(bevel); } } }