package { import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.filters.BlurFilter; import flash.geom.ColorTransform; import flash.geom.Point; [SWF(width=300, height=300, backgroundColor=0xFFFFFF)] public class graphic_flex_image_effects_04_Flex_ColorReplaceTest extends graphic_flex_image_effects_04_Flex_AbstractImageLoader { private static const COLOR_TO_REPLACE:uint = 0x819AD3; private static const TOLERANCE:uint = 32; private var _originalData:BitmapData; private var _isolatedData:BitmapData; /** * Constructor. Passes path of image to load to super class. */ public function graphic_flex_image_effects_04_Flex_ColorReplaceTest() { super("graphic-flex-image-effects-04-assets-goat.jpg"); } /** * Run after the image loads in super class. This creates an image of clouds, then removes pixels from * this image by using multiple calls to the threshold() method. The resulting image is copied into the * loaded image's data. */ override protected function runPostImageLoad():void { _originalData = _loadedBitmap.bitmapData; // creates a cloud image _isolatedData = createCloudImage(_originalData.width, _originalData.height); // finds the brightness to replace in each channel var red:uint = COLOR_TO_REPLACE>>16 & 0xFF; var green:uint = COLOR_TO_REPLACE>>8 & 0xFF; var blue:uint = COLOR_TO_REPLACE & 0xFF; // removes all pixels that are above and bloew the threshold around each channel's required value applyThreshold("<", Math.max(0, red-TOLERANCE)<<16, 0x00FF0000); applyThreshold(">", Math.min(255, red+TOLERANCE)<<16, 0x00FF0000); applyThreshold("<", Math.max(0, green-TOLERANCE)<<8, 0x0000FF00); applyThreshold(">", Math.min(255, green+TOLERANCE)<<8, 0x0000FF00); applyThreshold("<", Math.max(0, blue-TOLERANCE), 0x000000FF); applyThreshold(">", Math.min(255, blue+TOLERANCE), 0x000000FF); // blurs the clouds image slightly so that the edges where pixels were removed aren't jagggy _isolatedData.applyFilter(_isolatedData, _isolatedData.rect, new Point(), new BlurFilter(2, 2)); // copies the cloud image into the loaded image _originalData.copyPixels(_isolatedData, _isolatedData.rect, new Point()); _isolatedData.dispose(); addChild(_loadedBitmap); } /** * creates a cloud image using Perlin noise. This will be placed into the keyed out areas of the image. * * @param width The pixel width of the image to create. * @param height The pixel height of the image to create. * * @return The cloud image created. */ private function createCloudImage(width:Number, height:Number):BitmapData { var bitmapData:BitmapData = new BitmapData(width, height, true, 0x00000000); // noise only created in the red channel bitmapData.perlinNoise(100, 100, 3, 0, false, true, BitmapDataChannel.RED, true); // image lightened, with more lightening done in the red channel var colorTransform:ColorTransform = new ColorTransform(1.5, 1.4, 1.2, 1, 20, 20, 20); bitmapData.colorTransform(bitmapData.rect, colorTransform); return bitmapData; } /** * Calls theshold() on bitmap data. * * @param operation The operation to call as required by the threshold() method. * @param threshold The threshold value to pass to the threshold() method. * @param mask The mask value to pass to the threshold method. */ private function applyThreshold( operation:String, threshold:uint, mask:uint ):void { _isolatedData.threshold( _originalData, _originalData.rect, new Point(), operation, threshold, 0x00000000, mask, false ); } } }