Actionscript3でgray scale

February 29, 2008

まずサンプルを見てください。

yosemite-stream.jpg

これが、元画像です。

で、下のが2種類の方法でグレースケール化しています。
FLASHになっていますので、画面をクリックで切り替えてみてみてください。

demo of flash

まずは、example1のコードはこちらです。
ColorMatrixFilterのMatrixの値をRGB3等分にして平均化しています。

package {
	import flash.display.Sprite;
	import flash.filters.ColorMatrixFilter;

	public class Gray extends Sprite {
		private const OFFSET_R:Number = 1 / 3;
		private const OFFSET_G:Number = 1 / 3;
		private const OFFSET_B:Number = 1 / 3;

		public function Gray():void {
			var matrix:Array = [OFFSET_R, OFFSET_G, OFFSET_B, 0, 0,
								OFFSET_R, OFFSET_G, OFFSET_B, 0, 0,
								OFFSET_R, OFFSET_G, OFFSET_B, 0, 0,
								0, 0, 0, 1, 0];
			var cmf:ColorMatrixFilter = new ColorMatrixFilter(matrix);
			this.filters = [cmf];
		}
	}
}

これでも、別に構わないのですが、もう少し厳密に考えると違います。

なぜかというと、R,G,Bそれぞれの、本来の明度を無視しているからです。

簡単な図解のページ

こちらを見ると分かるのですが、当然0×00FF00の方が0×0000FFよりも明度が高いです。

そこで、輝度を計算する式があります。

Y(輝度) = 0.299 * R + 0.587 * G + 0.114 * B

これを見ると青の要素なんて殆ど反映されないのが分かります。

しかしexample1の方は、

Y =(R + G + B) / 3

で計算していますので、輝度の計算式と比較すると青の明度を拾いすぎ。ということになります。

example2のほうは輝度の計算式に沿ってグレイスケール化しています。
FLASHをもう一度見ていただくと、example2の方が、元画像の青の部分が暗いのが分かります。

というわけでこの部分を反映させたexample2のコードはこちら

	import flash.display.Sprite;
	import flash.filters.ColorMatrixFilter;

	public class Gray extends Sprite {
		private const OFFSET_R:Number = 0.299;
		private const OFFSET_G:Number = 0.587;
		private const OFFSET_B:Number = 0.114;

		public function Gray():void {
			var matrix:Array = [OFFSET_R, OFFSET_G, OFFSET_B, 0, 0,
								OFFSET_R, OFFSET_G, OFFSET_B, 0, 0,
								OFFSET_R, OFFSET_G, OFFSET_B, 0, 0,
								0, 0, 0, 1, 0];
			var cmf:ColorMatrixFilter = new ColorMatrixFilter(matrix);
			this.filters = [cmf];
		}
	}
}

0 Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2010 Muraken.biz | powered by WordPress with Barecity