How to extract specific colors from an image in Flex 2 (AS3)


Some time ago I was fronted by a problem in one of my problems, I needed to set a mask to a dynamic image – not very tough, the problem was that the mask had to be taken from a greyscale Image which was also dynamically loaded. The mask image was seperated into a black and a white area, the white area could be some sort of irregular form – and that made it tough ( I thought 😉 )

After a while of testing and writing code I dropped right after writing it I ended up with the Bitmap Class introduced with Flash 8 way ago. The thing I didn’t know was that there is a little but great function most people are using for creating nice effects:

BitmapData.threshold

Note that this isn’t a method from Bitmap, this goes for BitmapData.

Here is the explanation from the Adobe Docs for Flex 2.01:

threshold () method  

public function threshold(sourceBitmapData:BitmapData, sourceRect:Rectangle, destPoint:Point, operation:String, threshold:uint, color:uint = 0, mask:uint = 0xFFFFFFFF, copySource:Boolean = false):uint Tests pixel values in an image against a specified threshold and sets pixels that pass the test to new color values. Using the threshold() method, you can isolate and replace color ranges in an image and perform other logical operations on image pixels.

The threshold() method’s test logic is as follows:

  1. If ((pixelValue & mask) operation (threshold & mask)), then set the pixel to color;
  2. Otherwise, if copySource == true, then set the pixel to corresponding pixel value from sourceBitmap.

The operation parameter specifies the comparison operator to use for the threshold test. For example, by using “==” as the operation parameter, you can isolate a specific color value in an image. Or by using {operation: "<", mask: 0xFF000000, threshold: 0x7F000000, color: 0x00000000}, you can set all destination pixels to be fully transparent when the source image pixel’s alpha is less than 0x7F. You can use this technique for animated transitions and other effects.

Parameters

  sourceBitmapData:BitmapData — The input bitmap image to use. The source image can be a different BitmapData object or it can refer to the current BitmapData instance.
 
  sourceRect:Rectangle — A rectangle that defines the area of the source image to use as input.
 
  destPoint:Point — The point within the destination image (the current BitmapData instance) that corresponds to the upper-left corner of the source rectangle.
 
  operation:String — One of the following comparison operators, passed as a String: “<“, “<=”, “>”, “>=”, “==”, “!=”
 
  threshold:uint — The value that each pixel is tested against to see if it meets or exceeds the threshhold.
 
  color:uint (default = 0) — The color value that a pixel is set to if the threshold test succeeds. The default value is 0x00000000.
 
  mask:uint (default = 0xFFFFFFFF) — The mask to use to isolate a color component.
 
  copySource:Boolean (default = false) — If the value is true, pixel values from the source image are copied to the destination when the threshold test fails. If the value is false, the source image is not copied when the threshold test fails.

Returns

  uint — The number of pixels that were changed.

Throws

  TypeError — The sourceBitmapData, sourceRect destPoint or operation are null.
 
  ArgumentError — The operation string is not a valid operation

The full documentation can be found here

So if you look at this function it is commonly used to test all pixels in a BitmapData object for a certain color range and copy them (transformed) to another BitmapData object. But my intention was to extract a specific color range which isn’t too difficult:

// myImage is a completely loaded mx:Image
var sourceBitmapData:BitmapData = (myImage.content as Bitmap).bitmapData;

// The last parameter is important to make the target bitmap fully transparent
var targetBitmapData:BitmapData = new BitmapData(sourceBitmapData.width,
sourceBitmapData.height, 0x00000000);

targetBitmapData.threshold(sourceBitmapData, sourceBitmapData.rect,
new Point(0,0), "==", 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, false);

This will look at every pixel in sourceBitmapData, if the pixel is white it is copied as white pixel to the targetBitmapData, else it is dropped.

And that’s all, it’s amazingly easy to key out a specific color – you wouldn’t even need to generate a second BitmapData object, it can take it self as the target parameter (I don’t know if it will work, never tested that).

The best thing is that this is a native C method which works lightning fast even on big Bitmaps. Some people use this function to key out the background color from a webcam video or whatever you can imagine. So now go out and key some color 🙂

Advertisements
    • Visitor
    • July 10th, 2008

    Your articles are excellent and very useful, but your website is so hard to read. Could you please use a white color for text? Thank you.

    • Michael
    • June 6th, 2011

    Thank’s, very hopeful. This help me)

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: