Blog

ColorMatrix or how to “paint” MovieClip

Today I have to finish an application I’m developing for my company.
This application is downloading external parts of a house (png files) and displaying them on top of the house image. Thus the user can see the different texture he could chose.

The thing is a feature is to be able to “paint” those external materials.
So I’ve look around a bit for tips / tricks. I’ve found two classes for flash, both named ColorMatrix, one made by Grant Skinner the other by Quasimondo

The one from Grant doesn’t have any painting features, the one from Quasimondo has it but is not working the way I’ve wanted to.
What I’ve wanted is replacing “totally” a color by another one but still keeping the shadow, contrast, …

So I made this class, using bits of the Quaimondo one.
[as]
/*
* Class written by Xavier MARTIN (xxlm or zeflasher)
* http://dev.webbymx.net
* http://www.webbymx.net
* If you are using this class, I will be glad to receive a postcard of your place 🙂
* To do so please visit http://dev.webbymx.net and go in the about page to get my details…
*/

import flash.filters.ColorMatrixFilter;

class net.webbymx.geom.ColorMatrix {

/* ****************************************************************************
* PRIVATE STATIC VARIABLES
**************************************************************************** */
// Adobe luminance
private static var R_LUM : Number = .3;
private static var G_LUM : Number = .59;
private static var B_LUM : Number = .11;

private static var IDENTITY_MATRIX : Array = new Array (1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0);

/* ****************************************************************************
* PUBLIC VAR
**************************************************************************** */
public var matrix : Array;

/* ****************************************************************************
* CONSTRUCTOR
**************************************************************************** */
function ColorMatrix( mat : Array) {
if( mat != undefined ) matrix = mat
else mat = IDENTITY_MATRIX;
}

/* ****************************************************************************
* PRIVATE FUNCTIONS
**************************************************************************** */

/* ****************************************************************************
* PUBLIC FUNCTIONS
**************************************************************************** */
public function ajustLuminance( rgb : Number ) : Void {
var r:Number = ( ( rgb >> 16 ) & 0xff ) / 255;
var g:Number = ( ( rgb >> 8 ) & 0xff ) / 255;
var b:Number = ( rgb & 0xff ) / 255;
var l : Number = r * .3 + g * .59 + b * .11;

var mat : Array = new Array (l,l,l,0,0,
l,l,l,0,0,
l,l,l,0,0,
l,l,l,0,0);

concat( mat );
}

public function colorize( rgb : Number, percent : Number ) : Void {
var r:Number = ( ( rgb >> 16 ) & 0xff ) / 255;
var g:Number = ( ( rgb >> 8 ) & 0xff ) / 255;
var b:Number = ( rgb & 0xff ) / 255;

if ( percent == null) percent = 1;
var inv_percent : Number = 1 – percent;

var mat:Array = new Array ( inv_percent + percent * r * R_LUM, percent * r * G_LUM, percent * r * B_LUM, 0, 0,
percent * g * R_LUM, inv_percent + percent * g * G_LUM, percent * g * B_LUM, 0, 0,
percent * b * R_LUM,percent * b * G_LUM, inv_percent + percent * b * B_LUM, 0, 0,
0 , 0 , 0 , 1, 0 );
concat( mat );
}

/**
* Multiply the matrix to get the final result
* @param mat
*/
public function concat( mat : Array) : Void {

var mat_res : Array = new Array ();
var i:Number = 0;

for ( var r : Number = 0; r < 4; ++r ) { for ( var c : Number = 0; c < 5; ++c ) { mat_res[ i + c ] = mat[ i ] * matrix[ c ] + mat[ i + 1 ] * matrix[ c + 5 ] + mat[ i + 2 ] * matrix[ c + 10 ] + mat[ i + 3 ] * matrix[ c + 15 ] + ( c == 4 ? mat[ i + 4 ] : 0 ); } // go to next row i += 5; } matrix = mat_res; } /** * Convert the ColorMatrix to Grayscale * @param Void */ public function convertToGray ( Void ) : Void { matrix = [ .33 / R_LUM / 2, .33 / G_LUM / 2, .33 / B_LUM / 2, 0, 0, .33 / R_LUM / 2, .33 / G_LUM / 2, .33 / B_LUM / 2, 0, 0, .33 / R_LUM / 2, .33 / G_LUM / 2, .33 / B_LUM / 2, 0, 0, 0, 0, 0, 1, 0 ]; } public function getFilter( Void ) : ColorMatrixFilter { return new ColorMatrixFilter( matrix ); } public function paint( rgb : Number, percent : Number ) : Void { var r : Number = ( ( rgb >> 16 ) & 0xff ) > 0 ? ( ( rgb >> 16 ) & 0xff ) / 255 : 33 / 255;
var g : Number = ( ( rgb >> 8 ) & 0xff ) > 0 ? ( ( rgb >> 8 ) & 0xff ) / 255 : 33 / 255;
var b : Number = ( rgb & 0xff ) > 0 ? ( ( rgb ) & 0xff ) / 255 : 33 / 255;
var lu : Number = (r * .3 + g * .59 + b * .11);

// convert the image to grayscale
convertToGray();

// Add the color
if ( percent == null) percent = 1;
var inv_percent : Number = 1 – percent;

var rr : Number = inv_percent + ( percent * r * R_LUM );
var rg : Number = ( percent * r * G_LUM );
var rb : Number = ( percent * r * B_LUM );
var ra : Number = 0;
var ro : Number = lu;
var gr : Number = ( percent * g * R_LUM );
var gg : Number = ( inv_percent + percent * g * G_LUM );
var gb : Number = ( percent * g * B_LUM );
var ga : Number = 0;
var go : Number = lu;
var br : Number = ( percent * b * R_LUM );
var bg : Number = ( percent * b * G_LUM );
var bb : Number = ( inv_percent + percent * b * B_LUM );
var ba : Number = 0;
var bo : Number = lu;
var ar : Number = 0;
var ag : Number = 0;
var ab : Number = 0;
var aa : Number = 1;
var ao : Number = 0;

var mat:Array = new Array (rr, rg, rb, ra, ro,
gr, gg, gb, ga, go,
br, bg, bb, ba, bo,
ar, ag, ab, aa, ao);
concat( mat );
}

}
[/as]

[Download id not defined]

Here is a brief example showing how to use it
[as]
// Create new colour matrix object
var cm : ColorMatrix = new ColorMatrix();

// Define matrix via RGB number passed
cm.paint( 0xFF0000, 1);

// Apply the filter to the bitmapdata section to paint it
myBitmapData.applyFilter(myBitmapData, myBitmapData.rectangle,new Point(0,0), new flash.filters.ColorMatrixFilter( cm.matrix ) );
[/as]

I hope it will help some of you…

  • SunShine

    Hi,

    First, thanks for share this class !

    I’ve a little proble, when I use the the class on a movieclip with a colour gradation, the color graton disapear. At last, I’v only my movieclip with the specified color but I lost the other propertie like color gradtion.

    It’s normal ?

    Thank you

  • SunShine

    Hi,

    First, thanks for share this class !

    I’ve a little proble, when I use the the class on a movieclip with a colour gradation, the color graton disapear. At last, I’v only my movieclip with the specified color but I lost the other propertie like color gradtion.

    It’s normal ?

    Thank you

  • SunShine

    A part of my code :

    var matRGB : net.webbymx.geom.ColorMatrix = new net.webbymx.geom.ColorMatrix();
    matRGB.paint( color, percent);

    _mcBase.filters = [new ColorMatrixFilter(matRGB.matrix)];

    I think is ok, it is ?

    Thanks

  • SunShine

    A part of my code :

    var matRGB : net.webbymx.geom.ColorMatrix = new net.webbymx.geom.ColorMatrix();
    matRGB.paint( color, percent);

    _mcBase.filters = [new ColorMatrixFilter(matRGB.matrix)];

    I think is ok, it is ?

    Thanks