Friday 10 February 2012

BitmapData recolouring

There are at least four straightforward ways to recolour BitmapData. They all work by modifying the data directly, so the resulting BitmapData can be used as any other. Because of this they have no rendering cost, and so can be used fairly freely without impacting runtime performance.

The easiest is probably the colorTransform function. It can be used to tint or recolour a graphic, to e.g. brighten it to highlight it. I use it a lot to add colour to otherwise greyscale art, such as the tiles that make up the levels in Bug Tunnel Defense.

It takes the same ColorTransform class as can be used to set the transform. colorTransform of a DisplayObject. But instead of being a temporary effect it permanently modifies the data. This offers better performance, but cannot later be removed. This is best illustrated with two examples

// modify the BitmapData
var data:BitmapData, bmp:Bitmap;
data = new Logo(0, 0);
bmp = new Bitmap(data);
data.colorTransform(data.rect, new Colourise(Col.cRed));

// modify the Bitmap
var data:BitmapData, bmp:Bitmap;
data = new Logo(00);
bmp = new Bitmap(data);
bmp.transform.colorTransform = new Colourise(Col.cRed);

The examples are very similar, and only differ in how they use a ColorTransform (actually my version of it, a Colourise). The first modifies the actual data with the Colourise, while the second adds it so it can be later replaced or removed.

If the data cannot be modified, because it is instanced and used elsewhere, then it can be copied using the BitmapData clone function first. This can be re-done if the colouring needs updating, then used to set the Bitmap's bitmapData to update it.

The second method, as used on Wednesday, is the copyChannel function. This moves channels around, and is one of the few ways of manipulating the alpha channel directly. As such it's of limited use, but is good to know for those few times it is the only way to do something.

The third method is a ColorMatrixFilter. This extends the capabilities of the ColorTransform, in that it can do everything that can and more. In particular it can copy and blend data across channels, using a matrix, so can do much more complex transformations. Here is some code from Bug Tunnel Defense demonstrating its use

mat = new Array(0.2, 0.60.2, 00,
0.20.60.200,
0.20.60.200,
000, 10);
cmFilter = new ColorMatrixFilter(mat);
dat.applyFilter(dat, dat.rectnew Point(), cmFilter);

The above code merges the channels to generate a greyscale image, using more green than any other channel for input, and with equal rows so the RGB outputs are the same.

The last method is the only one I've not used, the palleteMap function. It could be used to do something like the curves operation in a graphics package, to e.g. rebalance a photo.

There are more general functions that can act on colours, though they are all more complex and often much slower. The data can be got a pixel at a time using getPixel or getPixel32, or all at once using getVector, then modified in any way desired. Or a ShaderFilter can be used with applyFilter, and again can modified in limitless ways.

No comments:

Post a Comment