Bitmap Edge and Orientation Transform Best
forked from Bitmap Edge and Orientation Transform (diff: 340)
ActionScript3 source code
/**
* Copyright j2e ( http://wonderfl.net/user/j2e )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/afdj
*/
// forked from j2e's Bitmap Edge and Orientation Transform
package {
/// written by j2e japanese2english@gmail.com
/// The function itself takes bitmapData and overwrites it with edge data.
/// The edge data is color-coded and can be used to determine
/// the orientation of the edge at any point when read or further manipulated.
/// Vertical edges are more red. Horizontal edges are more cyan/green.
/// Edges which go from upper right to lower left are more yellow, and
/// edges which go from upper left to lower right are more blue.
/// I think this is similar to the edge filter in Photoshop, but may be less efficient.
/// At any rate, this is the fixed version that I wrote from scratch. Use at your own risk (-_^)
/// This demo version takes a snapshot from a webcam when you click the mouse over
/// flash stage, and it shows the effects of the function.
import flash.display.AVM1Movie;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.BlendMode;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.media.Camera;
import flash.media.Video;
import flash.events.MouseEvent;
import flash.filters.ConvolutionFilter;
public class FlashTest extends Sprite {
//private var bmd:BitmapData = new BitmapData(0, 0, 200, 200);
private var cam:Camera;
private var vid:Video;
private var myBmd:BitmapData;
private const SMOOTHING:uint = 1;
// SMOOTHING defines how far away sampled pixels will be for comparison,
//higher numbers help to eliminate graininess
public function FlashTest() {
// write as3 code here..
cam = Camera.getCamera();
cam.setMode(320, 240, 15, false);
vid = new Video();
vid.attachCamera(cam);
stage.addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(event:MouseEvent):void {
myBmd = new BitmapData(cam.width, cam.height, false, 0);
myBmd.draw(vid);
//EdgeDetect(myBmd);
//EdgeTransform(myBmd);
FindFacePartsMidline(myBmd);
//HorEdges(myBmd);
//EnhanceEdges(myBmd, 1, 3);
BlurEdges(myBmd);
//SharpenEdges(myBmd);
//EdgeTransform(myBmd);
//FindEndpoints(myBmd);
//var rect:Rectangle = new Rectangle(0, 0, myBmd.width, myBmd.height);
//var pt:Point = new Point(0, 0);
//myBmd.copyChannel(myBmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.RED);
//myBmd.copyChannel(myBmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.GREEN);
this.addChild(new Bitmap(myBmd));
}
private function HorEdges(bmd:BitmapData):void {
var rect:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var pt:Point = new Point(0, 0);
var horFilter:ConvolutionFilter = new ConvolutionFilter(1, 3, [-1, 2, -1]);
bmd.applyFilter(bmd, rect, pt, horFilter);
}
/// Applies EdgeTransform to find edges and then enhances the edges
/// by enhancing those that are continuous or slightly disconnected
/// but which are implied by the orientation of surrounding edges
private function EnhanceEdges(bmd:BitmapData, factor:uint, times:uint):void {
var rect:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var pt:Point = new Point(0, 0);
var rFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, factor, factor, 0, 1, 0, factor, factor, 0]);
var gFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, factor, factor, 1, factor, factor, 0, 0]);
var bFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [factor, 0, 0, factor, 1, factor, 0, 0, factor]);
var redBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var greenBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var blueBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
redBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.RED, BitmapDataChannel.RED);
greenBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
blueBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);
while (times > 0) {
redBmd.applyFilter(bmd, rect, pt, rFilter);
greenBmd.applyFilter(bmd, rect, pt, gFilter);
blueBmd.applyFilter(bmd, rect, pt, bFilter);
times--;
}
bmd.copyChannel(redBmd, rect, pt, BitmapDataChannel.RED, BitmapDataChannel.RED);
bmd.copyChannel(greenBmd, rect, pt, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
bmd.copyChannel(blueBmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);
redBmd.dispose();
greenBmd.dispose();
blueBmd.dispose();
}
private function EdgeDetect(bmd:BitmapData):void {
var rect:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var pt:Point = new Point(0, 0);
var edgeFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [-1, -1, -1, -1, 8, -1, -1, -1, -1]);
bmd.applyFilter(bmd, rect, pt, edgeFilter);
}
private function BlurEdges(bmd:BitmapData):void {
var rect:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var pt:Point = new Point(0, 0);
var edgeFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [1,1,1,1,1,1,1,1,1]);
bmd.applyFilter(bmd, rect, pt, edgeFilter);
}
private function SharpenEdges(bmd:BitmapData):void {
var rect:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var pt:Point = new Point(0, 0);
var redBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var greenBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var blueBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var rSharpen:ConvolutionFilter = new ConvolutionFilter(3, 3, [-1, 0, 0, -1, 4, -1, 0, 0, -1]);
var gSharpen:ConvolutionFilter = new ConvolutionFilter(3, 3, [-1, -1, 0, 0, 4, 0, 0, -1, -1]);
var bSharpen:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, -1, -1, 0, 4, 0, -1, -1, 0]);
redBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.RED, BitmapDataChannel.RED);
greenBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
blueBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);
redBmd.applyFilter(bmd, rect, pt, rSharpen);
greenBmd.applyFilter(bmd, rect, pt, gSharpen);
blueBmd.applyFilter(bmd, rect, pt, bSharpen);
bmd.copyChannel(redBmd, rect, pt, BitmapDataChannel.RED, BitmapDataChannel.RED);
bmd.copyChannel(greenBmd, rect, pt, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
bmd.copyChannel(blueBmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);
redBmd.dispose();
greenBmd.dispose();
blueBmd.dispose();
}
private function FindEndpoints(bmd:BitmapData):void {
/// Cancels out continuous line segments which are in the expected (smooth) orientation
var rect:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var pt:Point = new Point(0, 0);
var rThreshold:uint = 0x00800000;
var gThreshold:uint = 0x00008000;
var bThreshold:uint = 0x00000080;
//var rFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [-1, 2, -1, -1, 2, -1, -1, 2, -1]);
//var gFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, 0, 2, 2, -4, 0, 0, 0]);
//var bFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, 0, -2, 0, 2, 0, 0, 0]);
var rFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, -1, -1, 0, 2, 0, -1, -1, 0]);
var gFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, -1, -1, 2, -1, -1, 0, 0]);
var bFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [-1, 0, 0, -1, 2, -1, 0, 0, -1]);
var rFilter2:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 2, 0, 0, 2, 0, 0, -4, 0]);
var gFilter2:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, 0, -4, 2, 2, 0, 0, 0]);
var bFilter2:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, 0, 2, 2, -4, 0, 0, 0]);
var rFilter3:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, -4, 0, 2, 0, 2, 0, 0]);
var gFilter3:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, -4, 0, 2, 0, 2, 0, 0]);
var bFilter3:ConvolutionFilter = new ConvolutionFilter(3, 3, [-4, 0, 0, 0, 2, 0, 0, 0, 2]);
var rFilter4:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, 2, 0, 2, 0, -4, 0, 0]);
var gFilter4:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, 2, 0, 2, 0, -4, 0, 0]);
var bFilter4:ConvolutionFilter = new ConvolutionFilter(3, 3, [2, 0, 0, 0, 2, 0, 0, 0, -4]);
var redBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var greenBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var blueBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var redBmd2:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var greenBmd2:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var blueBmd2:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var redBmd3:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var greenBmd3:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var blueBmd3:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var redBmd4:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var greenBmd4:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var blueBmd4:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
redBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.RED, BitmapDataChannel.RED);
greenBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
blueBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);
redBmd.threshold(redBmd, rect, pt, "<", rThreshold); // erase weak edges
greenBmd.threshold(greenBmd, rect, pt, "<", gThreshold);
blueBmd.threshold(blueBmd, rect, pt, "<", bThreshold);
/*redBmd2 = redBmd.clone();
greenBmd2 = greenBmd.clone();
blueBmd2 = blueBmd.clone();
redBmd3 = redBmd.clone();
greenBmd3 = greenBmd.clone();
blueBmd3 = blueBmd.clone();
redBmd4 = redBmd.clone();
greenBmd4 = greenBmd.clone();
blueBmd4 = blueBmd.clone();
redBmd.applyFilter(redBmd, rect, pt, rFilter);
greenBmd.applyFilter(greenBmd, rect, pt, gFilter);
blueBmd.applyFilter(blueBmd, rect, pt, bFilter);
redBmd2.applyFilter(bmd, rect, pt, rFilter2);
greenBmd2.applyFilter(bmd, rect, pt, gFilter2);
blueBmd2.applyFilter(bmd, rect, pt, bFilter2);
redBmd3.applyFilter(bmd, rect, pt, rFilter3);
greenBmd3.applyFilter(bmd, rect, pt, gFilter3);
blueBmd3.applyFilter(bmd, rect, pt, bFilter3);
redBmd4.applyFilter(bmd, rect, pt, rFilter4);
greenBmd4.applyFilter(bmd, rect, pt, gFilter4);
blueBmd4.applyFilter(bmd, rect, pt, bFilter4);
redBmd.draw(redBmd2, null, null, BlendMode.ADD);
greenBmd.draw(greenBmd2, null, null, BlendMode.ADD);
blueBmd.draw(blueBmd2, null, null, BlendMode.ADD);
redBmd.draw(redBmd3, null, null, BlendMode.ADD);
greenBmd.draw(greenBmd3, null, null, BlendMode.ADD);
blueBmd.draw(blueBmd3, null, null, BlendMode.ADD);
redBmd.draw(redBmd4, null, null, BlendMode.ADD);
greenBmd.draw(greenBmd4, null, null, BlendMode.ADD);
blueBmd.draw(blueBmd4, null, null, BlendMode.ADD);*/
bmd.copyChannel(redBmd, rect, pt, BitmapDataChannel.RED, BitmapDataChannel.RED);
bmd.copyChannel(greenBmd, rect, pt, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
bmd.copyChannel(blueBmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);
redBmd.dispose();
greenBmd.dispose();
blueBmd.dispose();
/*redBmd2.dispose();
greenBmd2.dispose();
blueBmd2.dispose();
redBmd3.dispose();
greenBmd3.dispose();
blueBmd3.dispose();
redBmd4.dispose();
greenBmd4.dispose();
blueBmd4.dispose();*/
}
private function FindFacePartsMidline(bmd:BitmapData):void {
// first find midline of symmetric objects on screen (looking primarily for lips/mouth and eyes)
var rect:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var pt:Point = new Point(0, 0);
var originalBmd:BitmapData = bmd.clone();
EdgeTransform(bmd);
var c:uint;
var f1Threshold:uint = 0x0000FFFF;
//bmd.threshold(bmd, rect, pt, "<", f1Threshold);
//bmd.copyChannel(bmd, rect, pt, BitmapDataChannel.GREEN, BitmapDataChannel.RED);
// Look for horizontal edges in cyan range
}
/// EdgeTransform takes bitmapData and overwrites it with its edge info
private function EdgeTransform(bmd:BitmapData):void {
var rect:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var pt:Point = new Point(0, 0);
/// Split input bitmap into different color channels to preserve color contrast effect
var redBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var greenBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var blueBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
redBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.RED, BitmapDataChannel.RED);
greenBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
blueBmd.copyChannel(bmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);
// Create bitmaps for writing edge info to
var nRedBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var nGreenBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var nBlueBmd:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0x000000);
var rgbR:uint;
var rgbG:uint;
var rgbB:uint;
var oldRgbR:uint;
var oldRgbG:uint;
var oldRgbB:uint;
var newRgbR:uint;
var newRgbG:uint;
var newRgbB:uint;
var vertOrientation:uint;
var horOrientation:uint;
var verthorOrientation:uint;
var horvertOrientation:uint;
var ul:uint;
var ll:uint;
var dl:uint;
var uu:uint;
var ur:uint;
var rr:uint;
var dr:uint;
var c:uint;
var dd:uint;
var y:uint;
var x:uint;
//// Go through each channel bitmap separately to preserve color contrast effect
//// First red channel
//// Go through each channel bitmap separately to preserve color contrast effect
//// First red channel
for (y = SMOOTHING; y < bmd.height; y++)
{
// Get pixel colors from a 2x3 box of bitmap
c = redBmd.getPixel(SMOOTHING, y);
ul = redBmd.getPixel(0, y-SMOOTHING);
ll = redBmd.getPixel(0, y);
dl = redBmd.getPixel(0, y+SMOOTHING);
uu = redBmd.getPixel(SMOOTHING, y-SMOOTHING);
dd = redBmd.getPixel(SMOOTHING, y+SMOOTHING);
for (x = SMOOTHING; x < bmd.width; x++)
{
// Get pixel colors from right-hand column of 3x3 box
ur = redBmd.getPixel(x+SMOOTHING, y-SMOOTHING);
rr = redBmd.getPixel(x+SMOOTHING, y);
dr = redBmd.getPixel(x+SMOOTHING, y+SMOOTHING);
//calculate the angle of the edge for the center point c
// depending upon surrounding edge pattern in 3x3 box
vertOrientation = uint((Math.abs(ll - c) + Math.abs(rr - c)) / 2);
horOrientation = uint((Math.abs(uu - c) + Math.abs(dd - c)) / 2);
verthorOrientation = uint((Math.abs(ur - c) + Math.abs(dl - c)) / 2);
horvertOrientation = uint((Math.abs(dr - c) + Math.abs(ul - c)) / 2);
// Give each instantaneous edge orientation angle a color code
rgbR = uint((vertOrientation + horvertOrientation)/0x010101);
rgbG = uint((horOrientation + horvertOrientation)/0x010101);
rgbB = uint((horOrientation + verthorOrientation)/0x010101);
rgbR *= 0x010000;
rgbG *= 0x000100;
rgbB *= 0x000001;
oldRgbR = nRedBmd.getPixel(x, y);
oldRgbG = nGreenBmd.getPixel(x, y);
oldRgbB = nBlueBmd.getPixel(x, y);
nRedBmd.setPixel(x, y, rgbR + oldRgbR);
nGreenBmd.setPixel(x, y, rgbG + oldRgbG);
nBlueBmd.setPixel(x, y, rgbB + oldRgbB);
//shift values for next pass when checking next 3x3 box
ll = c;
c = rr;
ul = uu;
uu = ur;
dl = dd;
dd = dr;
}
}
// Next blue channel
for (y = SMOOTHING; y < bmd.height; y++)
{
// Get pixel colors from a 2x3 box of bitmap
c = blueBmd.getPixel(SMOOTHING, y);
ul = blueBmd.getPixel(0, y-SMOOTHING);
ll = blueBmd.getPixel(0, y);
dl = blueBmd.getPixel(0, y+SMOOTHING);
uu = blueBmd.getPixel(SMOOTHING, y-SMOOTHING);
dd = blueBmd.getPixel(SMOOTHING, y+SMOOTHING);
for (x = SMOOTHING; x < bmd.width; x++)
{
// Get pixel colors from right-hand column of 3x3 box
ur = blueBmd.getPixel(x+SMOOTHING, y-SMOOTHING);
rr = blueBmd.getPixel(x+SMOOTHING, y);
dr = blueBmd.getPixel(x+SMOOTHING, y+SMOOTHING);
//calculate the angle of the edge for the center point c
// depending upon surrounding edge pattern in 3x3 box
vertOrientation = uint((Math.abs(ll - c) + Math.abs(rr - c)) / 2);
horOrientation = uint((Math.abs(uu - c) + Math.abs(dd - c)) / 2);
verthorOrientation = uint((Math.abs(ur - c) + Math.abs(dl - c)) / 2);
horvertOrientation = uint((Math.abs(dr - c) + Math.abs(ul - c)) / 2);
// Give each instantaneous edge orientation angle a color code
rgbR = uint((vertOrientation + horvertOrientation)/0x010101);
rgbG = uint((horOrientation + horvertOrientation)/0x010101);
rgbB = uint((horOrientation + verthorOrientation)/0x010101);
rgbR *= 0x010000;
rgbG *= 0x000100;
rgbB *= 0x000001;
oldRgbR = nRedBmd.getPixel(x, y);
oldRgbG = nGreenBmd.getPixel(x, y);
oldRgbB = nBlueBmd.getPixel(x, y);
nRedBmd.setPixel(x, y, rgbR + oldRgbR);
nGreenBmd.setPixel(x, y, rgbG + oldRgbG);
nBlueBmd.setPixel(x, y, rgbB + oldRgbB);
//shift values for next pass when checking next 3x3 box
ll = c;
c = rr;
ul = uu;
uu = ur;
dl = dd;
dd = dr;
}
}
/// Next green channel
for (y = SMOOTHING; y < bmd.height; y++)
{
// Get pixel colors from a 2x3 box of bitmap
c = greenBmd.getPixel(SMOOTHING, y);
ul = greenBmd.getPixel(0, y-SMOOTHING);
ll = greenBmd.getPixel(0, y);
dl = greenBmd.getPixel(0, y+SMOOTHING);
uu = greenBmd.getPixel(SMOOTHING, y-SMOOTHING);
dd = greenBmd.getPixel(SMOOTHING, y+SMOOTHING);
for (x = SMOOTHING; x < bmd.width; x++)
{
// Get pixel colors from right-hand column of 3x3 box
ur = greenBmd.getPixel(x+SMOOTHING, y-SMOOTHING);
rr = greenBmd.getPixel(x+SMOOTHING, y);
dr = greenBmd.getPixel(x+SMOOTHING, y+SMOOTHING);
//calculate the angle of the edge for the center point c
// depending upon surrounding edge pattern in 3x3 box
vertOrientation = uint((Math.abs(ll - c) + Math.abs(rr - c)) / 2);
horOrientation = uint((Math.abs(uu - c) + Math.abs(dd - c)) / 2);
verthorOrientation = uint((Math.abs(ur - c) + Math.abs(dl - c)) / 2);
horvertOrientation = uint((Math.abs(dr - c) + Math.abs(ul - c)) / 2);
// Give each instantaneous edge orientation angle a color code
rgbR = uint((vertOrientation + horvertOrientation)/0x010101);
rgbG = uint((horOrientation + horvertOrientation)/0x010101);
rgbB = uint((horOrientation + verthorOrientation)/0x010101);
rgbR *= 0x010000;
rgbG *= 0x000100;
rgbB *= 0x000001;
oldRgbR = nRedBmd.getPixel(x, y);
oldRgbG = nGreenBmd.getPixel(x, y);
oldRgbB = nBlueBmd.getPixel(x, y);
nRedBmd.setPixel(x, y, rgbR + oldRgbR);
nGreenBmd.setPixel(x, y, rgbG + oldRgbG);
nBlueBmd.setPixel(x, y, rgbB + oldRgbB);
//shift values for next pass when checking next 3x3 box
ll = c;
c = rr;
ul = uu;
uu = ur;
dl = dd;
dd = dr;
}
}
// Copy edge information from each respective channel over to original bitmap
bmd.copyChannel(nRedBmd, rect, pt, BitmapDataChannel.RED, BitmapDataChannel.RED);
bmd.copyChannel(nGreenBmd, rect, pt, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
bmd.copyChannel(nBlueBmd, rect, pt, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);
redBmd.dispose();
greenBmd.dispose();
blueBmd.dispose();
nRedBmd.dispose();
nGreenBmd.dispose();
nBlueBmd.dispose();
}
}
}
