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

酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

彩度調整

画像処理 Windows Store Apps

分割した記事で書かれていたのを「Windowsストアアプリで画像処理をおこなう - 酢ろぐ!」とひとつのエントリにまとめました。以下のエントリをご覧ください。




本記事では「ネガティブ(ネガポジ反転)変換 - 酢ろぐ!」で紹介したIEffectインターフェースをベースにして、彩度調整処理を実装します。

彩度というのは鮮やかさのことです。

SaturationEffect.csを新規作成してIEffectsの実装をしていきます。

using System;

namespace Softbuild.Media.Effects
{
    /// <summary>
    /// 彩度調整処理をおこなうクラス
    /// </summary>
    public class SaturationEffect : IEffect
    {
        /// <summary>
        /// 調整する彩度の倍率
        /// </summary>
        private double Saturation { get; set; }

        /// <summary>
        /// SaturationEffect クラスの新しいインスタンスを初期化します。
        /// </summary>
        /// <param name="saturation">彩度を表現する(0.0〜1.0 標準:0.5)</param>
        public SaturationEffect(double saturation)
        {
            Saturation = saturation * 2;
        }

        /// <summary>
        /// 彩度調整処理をおこなう
        /// </summary>
        /// <param name="width">ビットマップの幅</param>
        /// <param name="height">ビットマップの高さ</param>
        /// <param name="source">処理前のピクセルデータ</param>
        /// <returns>処理後のピクセルデータ</returns>
        public byte[] Effect(int width, int height, byte[] source)
        {
            int pixelCount = width * height;
            var dest = new byte[source.Length];

            for (int i = 0; i < pixelCount; i++)
            {
                var index = i * 4;

                // 処理前のピクセルの各ARGB要素を取得する
                double b = source[index + 0];
                double g = source[index + 1];
                double r = source[index + 2];
                double a = source[index + 3];

                // 単純平均法で輝度を求める
                double y = (b + g + r) / 3;

                // 輝度をベースに彩度を求める
                b = y + Saturation * (b - y);
                g = y + Saturation * (g - y);
                r = y + Saturation * (r - y);

                // 処理後のバッファへピクセル情報を保存する
                dest[index + 0] = (byte)Math.Min(255, Math.Max(0, b));
                dest[index + 1] = (byte)Math.Min(255, Math.Max(0, g));
                dest[index + 2] = (byte)Math.Min(255, Math.Max(0, r));
                dest[index + 3] = source[index + 3];
            }

            return dest;
        }
    }
}