Actionscript3でgray scale
まずサンプルを見てください。

これが、元画像です。
で、下のが2種類の方法でグレースケール化しています。
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];
}
}
}
