写真を加工する 5.2 各エフェクト

#wp7dev_jp

さて、それ以外にもさまざまフィルタを試してみましょう。

加算

単純に元画像にフィルタ画像を足します。全体的に明るく白っぽくなります。ちなみに Photoshop では覆い焼き(リニア)という名称です。

 // 加算
R = R1 + R2;

G = G1 + G2;

B = B1 + B2;
if (R > 255) R = 255;

if (G > 255) G = 255;

if (B > 255) B = 255;

image

減算

元画像からフィルタ画像を引きます。全体的に黒っぽくなります。

 // 減算
R = R1 - R2;

G = G1 - G2;

B = B1 - B2;
if ((int)R < 0) R = 0;

if ((int)G < 0) G = 0;

if ((int)B < 0) B = 0;

image

加算・減算・乗算フィルタ

3つをまとめて使うフィルタ。Enum を使ってまとめることで、オプションがつけやすくなります。こんな感じ

Mix.effect(src.Pixels, flt.Pixels, w, h, Mix.type.mixture);

Mix.cs

 public class Mix
{
    public enum type { plus, minus, mixture };
    public static int[] effect(
        int[] input1, int[] input2, int width, int height, 
        type mixtype )
    {
        int[] result = new int[input1.Length];
        for (int pixel = 0; pixel < input1.Length; pixel++)
        {
            uint color1 = (uint)input1[pixel];
            uint color2 = (uint)input2[pixel];
            uint A1 = (color1 >> 24);
            uint R1 = ((color1 >> 16) & 0xFF);
            uint G1 = ((color1 >> 8) & 0xFF);
            uint B1 = ((color1) & 0xFF);
            uint A2 = (color2 >> 24);
            uint R2 = ((color2 >> 16) & 0xFF);
            uint G2 = ((color2 >> 8) & 0xFF);
            uint B2 = ((color2) & 0xFF);
            uint A = A2;
            uint R = 0;
            uint G = 0;
            uint B = 0;
            switch( mixtype )
            {
                case type.plus:
                    // 加算
                    R = R1 + R2;
                    G = G1 + G2;
                    B = B1 + B2;
                    if (R > 255) R = 255;
                    if (G > 255) G = 255;
                    if (B > 255) B = 255;
                    break;
                case type.minus:
                    // 減算
                    R = R1 - R2;
                    G = G1 - G2;
                    B = B1 - B2;
                    if ((int)R < 0) R = 0;
                    if ((int)G < 0) G = 0;
                    if ((int)B < 0) B = 0;
                    break;
                case type.mixture:
                default:
                    // 乗算
                    A = A1 * A2 / 255;
                    R = R1 * R2 / 255;
                    G = G1 * G2 / 255;
                    B = B1 * B2 / 255;
                    break;
            }
            result[pixel] =
                ((int)A << 24) | ((int)R << 16) | ((int)G << 8) | (int)B;
        }
        return result;
    }
}

さて、だんだん困ったことになってきた。なぜ? .... 続く!

 

関連リンク