カラーマトリックスフィルター

(サンプル一覧を表示する)

FlashDevelop を使って、画像にカラーマトリックスフィルターを設定してみました。
カラーマトリックスフィルターを使うと、RGBA の各成分を 1 度に調整することができます。
ゲームで使用するときは、朝・昼・夜で太陽の光の加減を調節して登場キャラクターの色を変えるとか、
照明の色の違いによって部屋の雰囲気を変える時とかに使えると思います。
左が処理前の画像、右がFlashで処理済みの画像です。

Flash の実行画面
カラーマトリックスフィルター

Flashプレーヤーが入っていないか、JavaScriptが無効になっているようです。

Get Adobe Flash player

元の画像 カラーマトリックスフィルター
元のわんこの画像の中が白一色なので分かりにくいですが、
例えば赤いわんこの画像は、フィルターによって緑と青の成分を消しています。
この処理によって、白い部分は残りの赤の成分がそのまま出て、赤色として表示されています。
アルファ値はそのままです。アルファ値を変えると、半透明処理も同時に行うことができます。

ソースコード

package 
{
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	
	import flash.filters.BitmapFilter;
	import flash.filters.BitmapFilterQuality;
	import flash.filters.BitmapFilterType;
	import flash.filters.ColorMatrixFilter;
	
	/**
	 * カラーマトリックスフィルターのサンプル
	 * @author Hikipuro
	 */
	public class Main extends Sprite 
	{
		/**
		 * 埋め込み画像
		 */
		[Embed(source='../image/test001.png')]
		private var image1:Class;
		
		/**
		 * コンストラクタ
		 */
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		/**
		 * 初期化メソッド
		 * @param	e
		 */
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			var bitmap1:Bitmap = Bitmap(new image1);
			RegisterBitmap(bitmap1, 10, 10, 2.0);
			applyRed(bitmap1);
			
			var bitmap2:Bitmap = Bitmap(new image1);
			RegisterBitmap(bitmap2, 100, 10, 2.0);
			applyGreen(bitmap2);
			
			var bitmap3:Bitmap = Bitmap(new image1);
			RegisterBitmap(bitmap3, 190, 10, 2.0);
			applyBlue(bitmap3);
		}
			
		/**
		 * ステージにビットマップを登録して表示する
		 * @param	bitmap	表示するビットマップ
		 * @param	x		X 座標
		 * @param	y		Y 座標
		 * @param	scale	拡大率
		 */
		private function RegisterBitmap(bitmap:Bitmap, x:int, y:int, scale:Number):void
		{
			bitmap.smoothing = true;
			bitmap.cacheAsBitmap = true;
			bitmap.x = x;
			bitmap.y = y;
			bitmap.scaleX = scale;
			bitmap.scaleY = scale;
			addChild(bitmap);
		}
		
		/**
		 * 赤以外の色の効果を無くすフィルターを適用する
		 * @param	bitmap	適用先ビットマップ
		 */
        private function applyRed(bitmap:Bitmap):void {
            var child:DisplayObject = DisplayObject(bitmap);
            var matrix:Array = new Array();
            matrix = matrix.concat([1, 0, 0, 0, 0]); // red
            matrix = matrix.concat([0, 0, 0, 0, 0]); // green
            matrix = matrix.concat([0, 0, 0, 0, 0]); // blue
            matrix = matrix.concat([0, 0, 0, 1, 0]); // alpha

            applyFilter(child, matrix);
        }

		/**
		 * 緑以外の色の効果を無くすフィルターを適用する
		 * @param	bitmap	適用先ビットマップ
		 */
        private function applyGreen(bitmap:Bitmap):void {
            var child:DisplayObject = DisplayObject(bitmap);
            var matrix:Array = new Array();
            matrix = matrix.concat([0, 0, 0, 0, 0]); // red
            matrix = matrix.concat([0, 1, 0, 0, 0]); // green
            matrix = matrix.concat([0, 0, 0, 0, 0]); // blue
            matrix = matrix.concat([0, 0, 0, 1, 0]); // alpha

            applyFilter(child, matrix);
        }

		/**
		 * 青以外の色の効果を無くすフィルターを適用する
		 * @param	bitmap	適用先ビットマップ
		 */
        private function applyBlue(bitmap:Bitmap):void {
            var child:DisplayObject = DisplayObject(bitmap);
            var matrix:Array = new Array();
            matrix = matrix.concat([0, 0, 0, 0, 0]); // red
            matrix = matrix.concat([0, 0, 0, 0, 0]); // green
            matrix = matrix.concat([0, 0, 1, 0, 0]); // blue
            matrix = matrix.concat([0, 0, 0, 1, 0]); // alpha

            applyFilter(child, matrix);
        }

		/**
		 * カラーマトリックスフィルターを作成して、指定されたオブジェクトに適用する
		 * @param	child	適用先ディスプレイオブジェクト
		 * @param	matrix	色情報が入った行列
		 */
        private function applyFilter(child:DisplayObject, matrix:Array):void {
            var filter:ColorMatrixFilter = new ColorMatrixFilter(matrix);
            var filters:Array = new Array();
            filters.push(filter);
            child.filters = filters;
        }
	}
	
}		

プログラムはコンストラクタから開始されますが、コンストラクタ内に直接処理を入れると、表示したはずの画像が表示されない等の問題が出ることがあるようなので、いったんコンストラクタ内で init() イベントを設定することで開始時間をずらして、init() 内からコードを開始するような書き方になっています。これは、FlashDevelop で ActionScript3 のプロジェクトを作成すると最初からこういう構造になっています。

21 行目に、 image1 という変数が宣言されていますが、上の行に Embed 属性が付いていて、埋め込み画像を指すクラスをあらわしてます。埋め込み画像とは、SWF ファイルの中に入れてしまう画像のことです。Flash 実行時に URL から画像をダウンロードする必要がなくなるので、実験には便利です。埋め込み画像は Bitmap クラスに実体化して使用します。

44 〜 54行目が処理の中心になります。 カラーマトリックスフィルターを作って、画像を表示した後、フィルターを適用しています。 フィルターをいったん配列に入れていますが、これは、フィルターを複数かけるための構造で、 カラーマトリックス以外のフィルターを重ねてかねる時に使用します。 今回は 1 つだけフィルターをかけているので、配列に入れるのはおかしい気もしますが、 bitmap.filters のインターフェイスが配列型を要求するので、filters プロパティに設定するためだけに フィルターを配列に入れています。

参照

外部リンク