package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.geom.Point; import flash.geom.Rectangle; [SWF(width=600, height=300, backgroundColor=0x000000)] /** * Demonstrates how BitmapData's histogram() method can be used to access brightness level data for each all * channels of each pixel, and how this may be visually displayed. */ public class graphic_flex_image_effects_04_Flex_HistogramTest extends graphic_flex_image_effects_04_Flex_AbstractImageLoader { /** * Constructor. Passes path of image to load to super class. */ public function graphic_flex_image_effects_04_Flex_HistogramTest() { super("graphic-flex-image-effects-04-assets-goat.jpg"); } /** * Run after the image loads in super class. This gets the histrogram data and draws this in a colored * column chart in a new image that is displayed to the right of the loaded image. */ override protected function runPostImageLoad():void { var bitmapData:BitmapData = _loadedBitmap.bitmapData; addChild(_loadedBitmap); var histogram:Vector.> = bitmapData.histogram(); // retrieve the maximum number of pixels in a single brightness level; // this is used to set the top of the column chart var maxPixels:uint = getMaxPixels(histogram); // new image in which the histrogram data will be displayed var histogramData:BitmapData = new BitmapData(256, 256, false, 0xFF000000); // draws each individual color channel's histrogram data into the new image drawChannelData(maxPixels, histogramData, histogram[0], BitmapDataChannel.RED); drawChannelData(maxPixels, histogramData, histogram[1], BitmapDataChannel.GREEN); drawChannelData(maxPixels, histogramData, histogram[2], BitmapDataChannel.BLUE); // adds the bitmap data to a bitmap and the stage var histogramBitmap:Bitmap = new Bitmap(histogramData); histogramBitmap.x = bitmapData.width + (bitmapData.width-256)/2; histogramBitmap.y = (bitmapData.height-256)/2; addChild(histogramBitmap); } /** * Returns the maximum number of pixels in a single brightness level in all channels. * * @param histogram The histrogram data retrieved from an image. * * @return The maximum number of pixels in a single brightness level in all channels. */ private function getMaxPixels(histogram:Vector.>):uint { var maxPixels:uint = 0; var x:uint; var channel:Vector.; // run through all three channels for (var i:uint = 0; i < 3; i++) { channel = histogram[i]; // run through all 256 brightness levels for (x = 0; x < 256; x++) { maxPixels = Math.max(channel[x], maxPixels); } } return maxPixels; } /** * Draws a column chart of a channel's histogram data into the specified bitmap. * * @param maxPixels The maximum number of pixels that will be displayed on the y axis, defining chart size. * @param bitmapData The bitmap data in which to draw the channel data column chart. * @param channelData The histogram data for the channel to draw. * @param channel The channel of the image in which to draw the column chart. */ private function drawChannelData( maxPixels:uint, bitmapData:BitmapData, channelData:Vector., channel:uint ):void { // new bitmap data of exact same dimensions is used var channelBitmapData:BitmapData = bitmapData.clone(); var y:Number; // run through all 256 brightness levels and draw column for each for (var x:uint = 0; x < 256; x++) { // scale of the column is dictated by the number of pixels of that brightness in that channel // and the maxPixels value, which defines the height of the y axis and the chart y = channelData[x]/maxPixels*256; // draw a column from the bottom of the image up (256-y) channelBitmapData.fillRect(new Rectangle(x, 256-y, 1, y), 0xFFFFFFFF); } // copy the single channel's data into the final bitmap data bitmapData.copyChannel( channelBitmapData, channelBitmapData.rect, new Point(), channel, channel ); } } }