topical media & game development

talk show tell print

#graphic-flex-image-effects-04-Flex-PosterizeTest.ax

#graphic-flex-image-effects-04-Flex-PosterizeTest.ax [swf] [flash] flex


  package {
  
          import flash.display.Bitmap;
          import flash.display.BitmapData;
          import flash.display.BitmapDataChannel;
          import flash.display.BlendMode;
          import flash.geom.ColorTransform;
          import flash.geom.Point;
          import flash.geom.Rectangle;
  
          [SWF(width=900, height=300, backgroundColor=0x000000)]
  
          
Demonstrates how an image can be posterized through calls to the paletteMap() method of BitmapData.

  
          public class @ax-graphic-flex-image-effects-04-Flex-PosterizeTest extends graphic_flex_image_effects_04_Flex_LevelsTest {
  
                  
Run after the image loads in super class. This copies the loaded image twice and applies posterization to both copies before adding them to the stage.

  
                  override protected function runPostImageLoad():void {
                          var bitmapData:BitmapData = _loadedBitmap.bitmapData;
                          addChild(_loadedBitmap);
                          var clone:BitmapData = bitmapData.clone();
                          // posterizes first clone to 4 levels
                          posterize(clone, 4);
                          var bitmap:Bitmap = new Bitmap(clone);
                          bitmap.x = bitmapData.width;
                          addChild(bitmap);
                          clone = bitmapData.clone();
                          // posterizes first clone to 2 levels
                          posterize(clone, 2);
                          bitmap = new Bitmap(clone);
                          bitmap.x = bitmapData.width*2;
                          addChild(bitmap);
                  }
  
                  
Posterizes the specified image, reducing its number of colors, using the number of levels specified.
parameter: bitmapData The image to which to apply the posterization.
parameter: levels The number of colors in each channel to reduce the image to.

  
                  private function posterize(bitmapData:BitmapData, levels:uint):void {
                          // creates a new image with the image data from a single channel used in all three channels
                          var red:BitmapData = makeImageFromChannel(bitmapData, BitmapDataChannel.RED);
                          var green:BitmapData = makeImageFromChannel(bitmapData, BitmapDataChannel.GREEN);
                          var blue:BitmapData = makeImageFromChannel(bitmapData, BitmapDataChannel.BLUE);
                          // stores the channel image data into a vector for easy access
                          var sourceChannels:Vector.<BitmapData> = new Vector.<BitmapData>();
                          sourceChannels.push(red);
                          sourceChannels.push(green);
                          sourceChannels.push(blue);
  
                          // creates three new BitmapData instances that can be used to manipulate each color channel
                          red = new BitmapData(bitmapData.width, bitmapData.height);
                          green = red.clone();
                          blue = red.clone();
                          // stores what will be the adjusted channel image data into a vector for easy access
                          var adjustedChannels:Vector.<BitmapData> = new Vector.<BitmapData>();
                          adjustedChannels.push(red);
                          adjustedChannels.push(green);
                          adjustedChannels.push(blue);
  
                          var channelData:BitmapData;
                          var threshold:uint;
                          var colorTransform:ColorTransform;
                          var brightness:uint;
                          var j:uint;
                          // can reduce levels by 1 since the number of loops should be one less than the number of levels;
                          // for instance, a single iteration of the loop will produce an image of two colors, so a levels
                          // setting of 2 only needs to result in 1 loop
                          levels--;
                          for (var i:uint = 0; i < levels; i++) {
                                  // threshold will be higher on lower iterations of the loop, resulting in images with more black
                                  // for the lower iterations and images with more white for the higher iterations
                                  threshold = 255*((levels-i)/(levels+1));
                                  // the lower the iteration, the more the resulting channel image will be brightened before it
                                  // is layered in the composite adjusted channel
                                  brightness = 255*((levels-i-1)/levels);
                                  colorTransform = new ColorTransform(1, 1, 1, 1, brightness, brightness, brightness);
                                  // run through all three color channels
                                  for (j = 0; j < 3; j++) {
                                          // grab the original data
                                          channelData = sourceChannels[j].clone();
                                          // set the levels on the data to reduce the colors to 2
                                          setLevels(channelData, threshold, threshold, threshold);
                                          // draw the thresholded image into the adjusted channel after brightening it,
                                          // using MULTIPLY to overlay the grays
                                          adjustedChannels[j].draw(channelData, null, colorTransform, BlendMode.MULTIPLY);
                                  }
                          }
  
                          // copy the adjusted channels into the original image
                          copyChannel(red, bitmapData, BitmapDataChannel.RED);
                          copyChannel(green, bitmapData, BitmapDataChannel.GREEN);
                          copyChannel(blue, bitmapData, BitmapDataChannel.BLUE);
                  }
  
                  
Creates a new grayscale image using the data from a single channel, copying that channel's data into each channel of the new image.
parameter: bitmapData The image from which to copy the channel data.
parameter: channel The channel to create the grayscale image from.

  
                  private function makeImageFromChannel(
                          bitmapData:BitmapData,
                          channel:uint
                  ):BitmapData {
                          var clone:BitmapData = bitmapData.clone();
                          var rect:Rectangle = clone.rect;
                          var pt:Point = new Point();
                          // copy the same channel into all three channels of the new image
                          clone.copyChannel(bitmapData, rect, pt, channel, BitmapDataChannel.RED);
                          clone.copyChannel(bitmapData, rect, pt, channel, BitmapDataChannel.GREEN);
                          clone.copyChannel(bitmapData, rect, pt, channel, BitmapDataChannel.BLUE);
                          return clone;
                  }
  
                  
Copies the channel from the source into the destination bitmap data.
parameter: source The image from which to copy the channel data.
parameter: destination The image to copy the channel data into.
parameter: channel The channel to copy.

  
                  private function copyChannel(
                          source:BitmapData,
                          destination:BitmapData,
                          channel:uint
                  ):void {
                          destination.copyChannel(source, source.rect, new Point(), channel, channel);
                  }
  
          }
  
  }
  


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.