flash, bitmapdata, chroma key (or color key)
Thursday, March 19th, 2009here’s a routine to apply chroma (color) keying on a bitmapdata.
i’m not sure this is the best way to achieve chroma keying in flash, but it works.
an usage example:
we have imageBitmapData that is an image (imagine a panorama view), and we want to chroma key the blue sky in it. first we define the lower and higher blue values to be cutted off (they can be the same, if we want to chroma key exactly an rgb color and not a range). then we call the chromaKey method.
var imageBitmapData:BitmapData = new BitmapData(); //... load or draw here some content in imageBitmapData var myThresholdHigh:uint = 0xffacc9e5; //AARRGGBB, this is a light blue var myThresholdLow:uint = 0xff8aa2b8; //AARRGGBB, this is a dark blue imageBitmapData = chromaKey(imageBitmapData, myThresholdLow, myThresholdHigh);
and here’s the routine code:
import flash.display.*;
import flash.filters.*;
import flash.geom.*;
//if keepColor = false, returns the original bitmapdata with colors between colorLow and colorHi cutted off, otherwise (keepColor = true) return the inverse, that is the original bitmapdata with only colors from colorLow to colorHi
public static function chromaKey(myBitmapData:BitmapData, colorLow:uint, colorHi:uint, keepColor:Boolean = false):BitmapData
{
if ( keepColor )
{
//throw away pixels not in my color range
//red
myBitmapData.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
\"< \",
colorLow,
0x00000000,
0x00FF0000,
false
);
myBitmapData.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
\">“,
colorHi,
0×00000000,
0×00FF0000,
false
);
//green
myBitmapData.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
“< \",
colorLow,
0x00000000,
0x0000FF00,
false
);
myBitmapData.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
\">“,
colorHi,
0×00000000,
0×0000FF00,
false
);
//blue
myBitmapData.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
“< \",
colorLow,
0x00000000,
0x000000FF,
false
);
myBitmapData.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
\">“,
colorHi,
0×00000000,
0×000000FF,
false
);
}
else
{
//throw away pixels in my color range
//red
var myBitmapDataRedLow:BitmapData = new BitmapData(myBitmapData.width, myBitmapData.height);
myBitmapDataRedLow = myBitmapData.clone();
myBitmapDataRedLow.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
“>=”,
colorLow,
0×00000000,
0×00FF0000,
false
);
var myBitmapDataRedHigh:BitmapData = new BitmapData(myBitmapData.width, myBitmapData.height);
myBitmapDataRedHigh = myBitmapData.clone();
myBitmapDataRedHigh.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
“< =\",
colorHi,
0x00000000,
0x00FF0000,
false
);
//merge low and hi
myBitmapDataRedLow.draw(myBitmapDataRedHigh,null,null,BlendMode.MULTIPLY,null,false);
//green
var myBitmapDataGreenLow:BitmapData = new BitmapData(myBitmapData.width, myBitmapData.height);
myBitmapDataGreenLow = myBitmapData.clone();
myBitmapDataGreenLow.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
\">=”,
colorLow,
0×00000000,
0×0000FF00,
false
);
var myBitmapDataGreenHigh:BitmapData = new BitmapData(myBitmapData.width, myBitmapData.height);
myBitmapDataGreenHigh = myBitmapData.clone();
myBitmapDataGreenHigh.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
“< =\",
colorHi,
0x00000000,
0x0000FF00,
false
);
//merge low and hi
myBitmapDataGreenLow.draw(myBitmapDataGreenHigh,null,null,BlendMode.MULTIPLY,null,false);
//blue
var myBitmapDataBlueLow:BitmapData = new BitmapData(myBitmapData.width, myBitmapData.height);
myBitmapDataBlueLow = myBitmapData.clone();
myBitmapDataBlueLow.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
\">=”,
colorLow,
0×00000000,
0×000000FF,
false
);
var myBitmapDataBlueHigh:BitmapData = new BitmapData(myBitmapData.width, myBitmapData.height);
myBitmapDataBlueHigh = myBitmapData.clone();
myBitmapDataBlueHigh.threshold(
myBitmapData,
new Rectangle(0, 0, myBitmapData.width, myBitmapData.height),
new Point(0,0),
“< =\",
colorHi,
0x00000000,
0x000000FF,
false
);
//merge low and hi
myBitmapDataBlueLow.draw(myBitmapDataBlueHigh,null,null,BlendMode.MULTIPLY,null,false);
//merge channels in output bitmapdata
myBitmapData = new BitmapData(myBitmapData.width, myBitmapData.height, true, 0x00000000);
myBitmapData.draw(myBitmapDataRedLow,null,null,BlendMode.MULTIPLY,null,false);
myBitmapData.draw(myBitmapDataGreenLow,null,null,BlendMode.MULTIPLY,null,false);
myBitmapData.draw(myBitmapDataBlueLow,null,null,BlendMode.MULTIPLY,null,false);
}
return myBitmapData;
}


