首页  ·  知识 ·  编程语言
颜色模式转换(RGB&HSB)
飘遥的Blog  http://www.cnblogs.com/zxjay/  .NET  编辑:dezai  图片来源:网络
颜色表示模式有多种,比较常用的(如Windows调色板)有减色系统的RGB(红,绿,蓝)和HSB(色调,饱和度,亮度),这里简单实现RGB跟HSB之间的转换。简单算法

颜色表示模式有多种,比较常用的(如Windows调色板)有减色系统的RGB(红,绿,蓝)和HSB(色调,饱和度,亮度),这里简单实现RGB跟HSB之间的转换。
简单算法如下:
C#:

///


/// HSB用float数据类型表示
///

static void RGB2HSB(int r, int g, int b, out float hue, out float sat, out float bri)
{
    int minval = Math.Min(r, Math.Min(g, b));
    int maxval = Math.Max(r, Math.Max(g, b));

    //bri
    bri = (float)(maxval + minval) / 510;

    //sat
    if (maxval == minval)
    {
        sat = 0.0f;
    }
    else
    {
        int sum = maxval + minval;

        if (sum > 255)
        {
            sum = 510 - sum;
        }

        sat = (float)(maxval - minval) / sum;
    }

    //hue
    if (maxval == minval)
    {
        hue = 0.0f;
    }
    else
    {
        float diff = (float)(maxval - minval);
        float rnorm = (maxval - r) / diff;
        float gnorm = (maxval - g) / diff;
        float bnorm = (maxval - b) / diff;

        hue = 0.0f;

        if (r == maxval)
        {
            hue = 60.0f * (6.0f + bnorm - gnorm);
        }

        if (g == maxval)
        {
            hue = 60.0f * (2.0f + rnorm - bnorm);
        }

        if (b == maxval)
        {
            hue = 60.0f * (4.0f + gnorm - rnorm);
        }

        if (hue > 360.0f)
        {
            hue = hue - 360.0f;
        }
    }
}

///


/// HSB用int数据类型表示,同Winform中的ColorDialog中HSB的表示
///

static void RGB2HSB(int r, int g, int b, out int hue, out int sat, out int bri)
{
    float fHue, fSat, fBri;

    RGB2HSB(r, g, b, out fHue, out fSat, out fBri);

    hue = (int)((fHue / 360.0f) * 240 + 0.5);
    sat = (int)(fSat * 241 + 0.5);
    bri = (int)(fBri * 241 + 0.5);

    if (hue > 239)
    {
        hue = 239;
    }

    if (sat > 240)
    {
        sat = 240;
    }

    if (bri > 240)
    {
        bri = 240;
    }
}

///


/// 传入的HSB用int型表示,如果用float型表示,可将下面的转换成float过程去掉
///

static void HSB2RGB(int hue, int sat, int bri, out int r, out  int g, out int b)
{
    //begin:HSB转换为float
    if (hue > 239)
    {
        hue = 239;
    }
    else
    {
        if (hue < 0)
        {
            hue = 0;
        }
    }

    if (sat > 240)
    {
        sat = 240;
    }
    else
    {
        if (sat < 0)
        {
            sat = 0;
        }
    }

    if (bri > 240)
    {
        bri = 240;
    }
    else
    {
        if (bri < 0)
        {
            bri = 0;
        }
    }

    float H = hue / 239.0f;
    float S = sat / 240.0f;
    float L = bri / 240.0f;

    //end:HSB转换为float

    float red = 0, green = 0, blue = 0;
    float d1, d2;

    if (L == 0)
    {
        red = green = blue = 0;
    }
    else
    {
        if (S == 0)
        {
            red = green = blue = L;
        }
        else
        {
            d2 = (L <= 0.5f) ? L * (1.0f + S) : L + S - (L * S);
            d1 = 2.0f * L - d2;

            float[] d3 = new float[] { H + 1.0f / 3.0f, H, H - 1.0f / 3.0f };
            float[] rgb = new float[] { 0, 0, 0 };

            for (int i = 0; i < 3; i++)
            {
                if (d3[i] < 0)
                {
                    d3[i] += 1.0f;
                }

                if (d3[i] > 1.0f)
                {
                    d3[i] -= 1.0f;
                }

                if (6.0f * d3[i] < 1.0f)
                {
                    rgb[i] = d1 + (d2 - d1) * d3[i] * 6.0f;
                }
                else
                {
                    if (2.0f * d3[i] < 1.0f)
                    {
                        rgb[i] = d2;
                    }
                    else
                    {
                        if (3.0f * d3[i] < 2.0f)
                        {
                            rgb[i] = (d1 + (d2 - d1) * ((2.0f / 3.0f) - d3[i]) * 6.0f);
                        }
                        else
                        {
                            rgb[i] = d1;
                        }
                    }
                }
            }

            red = rgb[0];
            green = rgb[1];
            blue = rgb[2];
        }
    }

    red = 255.0f * red;
    green = 255.0f * green;
    blue = 255.0f * blue;

    if (red < 1)
    {
        red = 0.0f;
    }
    else
    {
        if (red > 255.0f)
        {
            red = 255.0f;
        }
    }

    if (green < 1)
    {
        green = 0.0f;
    }
    else
    {
        if (green > 255.0f)
        {
            green = 255.0f;
        }
    }

    if (blue < 1)
    {
        blue = 0.0f;
    }
    else
    {
        if (blue > 255.0f)
        {
            blue = 255.0f;
        }
    }

    r = (int)(red + 0.5);
    g = (int)(green + 0.5);
    b = (int)(blue + 0.5);
}

颜色转化时由于int跟float强制转换以及精度表示等原因,会产生误差。如一个RGB转换为HSB再转换为RGB会于原RGB有一定的误差。

参考资料:Mono

本文作者:飘遥的Blog 来源:http://www.cnblogs.com/zxjay/
CIO之家 www.ciozj.com 微信公众号:imciow
    >>频道首页  >>网站首页   纠错  >>投诉
版权声明:CIO之家尊重行业规范,每篇文章都注明有明确的作者和来源;CIO之家的原创文章,请转载时务必注明文章作者和来源;
延伸阅读