読者です 読者をやめる 読者になる 読者になる

心魅 - cocoromi -

半角スペース時々全角

flash.filters.ColorMatrixFilter

ColorMatrixFilter
http://livedocs.adobe.com/flex/3/langref/flash/filters/ColorMatrixFilter.html

このフィルターを使うと、フィルター対象の各ピクセルのRGBA値に対して一様な変換を加えることが出来ます。

何はともあれ、さんぷる


ボタンをぽちぽちすると、フィルターをオンオフします。

http://umezo.tsuyabu.in/samples/flex/colormatrixfilter/ColorMatrixFilter.swf

<?xml version="1.0"?>
<mx:Application 
	xmlns:mx="http://www.adobe.com/2006/mxml"
	initialize="init();"
>
	<mx:Script>
		<![CDATA[
		import flash.filters.ColorMatrixFilter;
		import mx.controls.Image;
		
		private var cmFilter : ColorMatrixFilter ;
		private var flag : Boolean;
		
		private function init():void {
			//ColorMatrixFilterの初期化
			cmFilter = new ColorMatrixFilter([
				//パラメータは後で解説するにょ
				1 , 0 , 0 , 0 , 0 ,
				0 , 0 , 0 , 0 , 0 , 
				0 , 0 , 0 , 0 , 0 ,
				0 , 0 , 0 , 1 , 0
			]);
			
			//切り替え用のフラグ
			flag = false;
		}

		private function toggleFilter():void {
			//DisplayObjectで定義されているfiltersプロパティにフィルターの配列を設定するとフィルターが適用される。

			img.filters = flag ? [] : [ cmFilter ];
			flag = !flag;
		}
			
		]]>
		
	</mx:Script>
	<mx:Image id="img" source="@Embed(source='../res/umezo_p.gif')" ></mx:Image>
	<mx:Button click="toggleFilter();" label="switch"></mx:Button>
</mx:Application>

パラメータ解説


さて、今回のキモはもちろん↓ココ

	cmFilter = new ColorMatrixFilter([
		//パラメータは後で解説するにょ
		1 , 0 , 0 , 0 , 0 ,
		0 , 0 , 0 , 0 , 0 , 
		0 , 0 , 0 , 0 , 0 ,
		0 , 0 , 0 , 1 , 0
	]);

この部分で変換用のパラメータを1次元配列で渡しています。
さて、問題はこの配列が何を表しているのかということになってきます。

ColorMatrixFilterの変換処理


結論から言うと、以下のサイトで説明されている、以下の行列演算がすべてです。
これで、解る人は、この先読まなくてもOKです。

boreal-kiss.com [AS3]ColorMatrixFilterメモ
http://blog.boreal-kiss.com/2008/04/08113113.html
f:id:umezo:20090122215305p:image

?????でっていう


さて、上の式の意味を考えていきましょう。
ColorMatrixFilterではn番目のピクセルのRGBA値からフィルタ後のn番目のRGBAを計算します。

f:id:umezo:20090122221444p:image


もう少し細かく見ていきましょう。
ひとまず、フィルタ後のR値がどんな流れで計算されるのか図で見てみましょう。
f:id:umezo:20090122223202p:image

ポイントはフィルタ前のRGBA値すべてを使って、次のR値を計算しているというところです。
このときフィルタ前のRGBA値のうちどの値をどれぐらいの強さで次ぎのR値に反映させるかを決めているのが、先ほどのこの部分

	cmFilter = new ColorMatrixFilter([
		//パラメータは後で解説するにょ
		1 , 0 , 0 , 0 , 0 ,
		0 , 0 , 0 , 0 , 0 , 
		0 , 0 , 0 , 0 , 0 ,
		0 , 0 , 0 , 1 , 0
	]);

のこの部分。配列の先頭4つになります。

		1 , 0 , 0 , 0 , 0 ,

コレがそれぞれ先頭からR値の強さ、G値の強さ、B値の強さ、A値の強さ、(5個目は保留)になっています。また強さは実数で設定値で設定するので、上記の設定だと、R値は元のまま(1倍)、他は反映しない(0倍)。つまり、ここのパラメータの意味するところは、フィルタ後のR値は前のR値を引き継ぐという意味になります。

残りのGBA値のためのパラメータはR値の続きの部分になります。

	cmFilter = new ColorMatrixFilter([
		//パラメータは後で解説するにょ
		1 , 0 , 0 , 0 , 0 , //次のR値計算のためのパラメータ
		0 , 0 , 0 , 0 , 0 , //次のG値計算のためのパラメータ
		0 , 0 , 0 , 0 , 0 , //次のB値計算のためのパラメータ
		0 , 0 , 0 , 1 , 0   //次のA値計算のためのパラメータ
	]);

GとBはすべての強さが0なので前のRGBA値がどんな値だろうと、計算すると0となります。また、アルファ値はRGB値に0、アルファに1が指定してあるため、色は無視し元のアルファを引き継ぐことになります。

ココまでをおさらいすると

  1. フィルタ後のR->フィルタ前のR
  2. フィルタ後のG->0
  3. フィルタ後のB->0
  4. フィルタ後のA->フィルタ前のA

となっており、フィルタ後は元の画像の赤成分だけが残ることになります。

5番目のパラメータ


五番目の数値について説明します。

		1 , 0 , 0 , 0 , 0 ,

5番目の値は前章で求めたフィルタ後の数値に単純に足し算されます。なので、↑を↓の洋に書き換えると

		1 , 0 , 0 , 0 , 255 ,

前がどんな値であろうと、255が足され、すべてのピクセルのR値がMAXの255に設定されることになります。

練習


自在にパラメータをいじれるように色々考えて見ましょう。

真っ黒にする

↓コレは間違いですよー???

0 , 0 , 0 , 0 , 0 , //次のR値計算のためのパラメータ
0 , 0 , 0 , 0 , 0 , //次のG値計算のためのパラメータ
0 , 0 , 0 , 0 , 0 , //次のB値計算のためのパラメータ
0 , 0 , 0 , 0 , 0   //次のA値計算のためのパラメータ

真っ白にする

誤答例

1 , 1 , 1 , 1 , 0 , //次のR値計算のためのパラメータ
1 , 1 , 1 , 1 , 0 , //次のG値計算のためのパラメータ
1 , 1 , 1 , 1 , 0 , //次のB値計算のためのパラメータ
1 , 1 , 1 , 1 , 0   //次のA値計算のためのパラメータ

赤と緑を入れ替える

赤を緑に、緑に赤を出力するには?

? , ? , ? , ? , ? , //次のR値計算のためのパラメータ
? , ? , ? , ? , ? , //次のG値計算のためのパラメータ
0 , 0 , 1 , 0 , 0 , //次のB値計算のためのパラメータ
0 , 0 , 0 , 1 , 0   //次のA値計算のためのパラメータ

青を強める

0だと弱く1だとそのまま

1 , 0 , 0 , 0 , 0 , //次のR値計算のためのパラメータ
0 , 1 , 0 , 0 , 0 , //次のG値計算のためのパラメータ
0 , 0 , ? , 0 , 0 , //次のB値計算のためのパラメータ
0 , 0 , 0 , 1 , 0   //次のA値計算のためのパラメータ

まとめ


ColorMatrixFilterを使うと、画像などDisplayObjectのサブクラスに対して、色変換を行うことができます。
色変換のパラメータはコンストラクタ引数やメソッドで指定し、その時の配列の要素5ずつがそれぞれフィルタ後のRGBA値の計算に用いられます。

というわけで、長かったですが、ColorMatrixFilterの説明は終わりです。