2011年4月7日木曜日

C# RGB ⇔ HSV 相互変換 改

RGB⇔HSVができるHSVの構造体です。

コード



//RGBからHSV
//
// HSVColor構造体
//  Hiroaki,Komori 
//
using System;
using System.Drawing;
using System.Linq;

public struct HSV
{
    private int _h;
    private int _s;
    private int _v;

    public int H
    {
        get { return _h; }
        set { _h = value; }
    }

    public int S
    {
        get { return _s; }
        set { _s = value; }
    }

    public int V
    {
        get { return _v; }
        set { _v = value; }
    }

    public HSV(int h, int s, int v)
    {
        _h = h;
        _s = s;
        _v = v;
    }

    ///
    /// ColorからHSV
    ///
    ///    public HSV(Color rgb)
    {
        byte[] cols = new byte[] { rgb.R, rgb.G, rgb.B };
        double max = cols.Max();
        double min = cols.Min();

        //Vを求める
        _v = (int)max;

        //RGBすべてが同じ場合 HとSは0 
        if (max == min)
        {
            _h = 0;
            _s = 0;
        }
        else
        {
            //Sを求める
            _s = (int)(((max - min) * 255) / max);

            //Hを求める
            _h = 0;

            if (max == rgb.R)
            {
                _h = (int)(60 * (rgb.G - rgb.B) / (max - min));
                if (_h < 0)
                {
                    _h += 360;
                }
            }
            else if (max == rgb.G)
            {
                _h = (int)(60 * (2 + (rgb.B - rgb.R) / (max - min)));
                if (_h < 0)
                {
                    _h += 360;
                }
            }
            else if (max == rgb.B)
            {
                _h = (int)(60 * (4 + (rgb.R - rgb.G) / (max - min)));
                if (_h < 0)
                {
                    _h += 360;
                }
            }
        }
    }

    ///
    /// Colorへ変換
    ///
    //////
    public Color ToColor()
    {
        return HSV.FromRgb(_h, _s, _v);
    }

    ///
    /// Colorへ変換
    ///
    //////
    public static Color FromRgb(HSV hsv)
    {
        return HSV.FromRgb(hsv.H, hsv.S, hsv.V);
    }

    ///
    /// Colorへ変換
    ///
    //////
    public static Color FromRgb(int h, int s, int v)
    {
        if (h == 360)
        {
            h = 0;
        }

        int Hi = (int)(Math.Floor(h / 60d) % 6);

        int f = (int)((h / 60f) - Hi);
        int p = (int)((v / 255f) * (1 - (s / 255f)));
        int q = (int)((v / 255f) * (1 - f * (s / 255f)));
        int t = (int)((v / 255f) * (1 - (1 - f) * (s / 255f)));

        p *= 255;
        q *= 255;
        t *= 255;

        Color rgb = new Color();

        switch (Hi)
        {
            case 0:
                rgb = Color.FromArgb(v, t, p);
                break;
            case 1:
                rgb = Color.FromArgb(q, v, p);
                break;
            case 2:
                rgb = Color.FromArgb(p, v, t);
                break;
            case 3:
                rgb = Color.FromArgb(p, q, v);
                break;
            case 4:
                rgb = Color.FromArgb(t, p, v);
                break;
            case 5:
                rgb = Color.FromArgb(v, p, q);
                break;
        }

        return rgb;
    }

    ///
    ///文字列に変換
    ///
    ///
    public override string ToString()
    {
        string result = string.Format("HSV [H={0}, S={1}, V={2}]", _h, _s, _v);
        return result;
    }
}

0 件のコメント:

コメントを投稿