快速、优化和精确的RGB<-&燃气轮机;C语言中的HSB转换代码

快速、优化和精确的RGB<-&燃气轮机;C语言中的HSB转换代码,c,graphics,colors,C,Graphics,Colors,我正在寻找在纯C中快速、准确地实现RGB到HSB和HSB到RGB。请注意,我专门寻找色调、饱和度、亮度,而不是HSL(亮度) 当然,我已经在谷歌上搜索了很多,但是速度在这里是最重要的,我正在寻找任何关于可靠、快速、可靠代码的具体建议。首先 HSB和HLS的开发是为了在用户必须以数字方式指定颜色的时代指定数字色调、饱和度和亮度(或色调、亮度和饱和度)。HSB和HLS的常用配方与色觉特性有关。既然用户可以直观地选择颜色,或者选择与其他媒体(如PANTONE)相关的颜色,或者使用基于感知的系统,如L*

我正在寻找在纯C中快速、准确地实现RGB到HSB和HSB到RGB。请注意,我专门寻找色调、饱和度、亮度,而不是HSL(亮度)

当然,我已经在谷歌上搜索了很多,但是速度在这里是最重要的,我正在寻找任何关于可靠、快速、可靠代码的具体建议。

首先

HSB和HLS的开发是为了在用户必须以数字方式指定颜色的时代指定数字色调、饱和度和亮度(或色调、亮度和饱和度)。HSB和HLS的常用配方与色觉特性有关。既然用户可以直观地选择颜色,或者选择与其他媒体(如PANTONE)相关的颜色,或者使用基于感知的系统,如L*u*v*和L*a*b*,那么HSB和HLS应该放弃

看看开源Java实现


Boost库(我知道,它是C++)似乎一度包含到HSB的转换,但现在我只能找到亮度转换()

我建议使用查找表来存储HSB和RGB值。首先将RGB值(每个组件大概8位)转换为16位值(每个组件5位)。HSB值(也是16位值)可以以相同的方式转换,由此,色调分量可能使用比饱和度和亮度更多的位,每个分量可能使用8位,而饱和度和亮度各使用4位。当然,当从HSB转换为RGB时,情况正好相反。

这里是标准C中的一个简单实现

没有进一步的背景,这是最好的。也许你想多解释一下

  • 如何存储RGB样本(首先是位/像素!)
  • 如何存储像素数据(是否要高效转换较大的缓冲区,如果是,组织是什么)
  • 您希望如何表示输出(我现在假设为浮动)
我可以提出一个进一步优化的版本(可能是一个很好地利用SSE4指令的版本…)

综上所述,当使用优化进行编译时,这并不太糟糕:

#include <stdio.h>
#include <math.h>

typedef struct RGB_t { unsigned char red, green, blue; } RGB;
typedef struct HSB_t { float hue, saturation, brightness; } HSB;

/*
 * Returns the hue, saturation, and brightness of the color.
 */
void RgbToHsb(struct RGB_t rgb, struct HSB_t* outHsb)
{
    // TODO check arguments

    float r = rgb.red / 255.0f;
    float g = rgb.green / 255.0f;
    float b = rgb.blue / 255.0f;
    float max = fmaxf(fmaxf(r, g), b);
    float min = fminf(fminf(r, g), b);
    float delta = max - min;
    if (delta != 0)
    {
        float hue;
        if (r == max)
        {
            hue = (g - b) / delta;
        }
        else
        {
            if (g == max)
            {
                hue = 2 + (b - r) / delta;
            }
            else
            {
                hue = 4 + (r - g) / delta;
            }
        }
        hue *= 60;
        if (hue < 0) hue += 360;
        outHsb->hue = hue;
    }
    else
    {
        outHsb->hue = 0;
    }
    outHsb->saturation = max == 0 ? 0 : (max - min) / max;
    outHsb->brightness = max;
}

关于优化策略的好提示。然而,所做的权衡是无法争辩的;OP的要求太模糊(快速、准确的实现),除非您使用HSB,因为您无法更改某些外部要求,否则请放弃它。HSB(和HSL一起)是一个基本上被破坏的颜色模型,它与现实无关,并且会导致一些可怕的事情,比如颜色在改变色调时改变强度。(从数学上讲,转换为灰度不会随着色相轮的旋转而改变。)这是在sRGB还是线性RGB中?答案是:HSV基于sRGB颜色空间。
int main()
{
    struct RGB_t rgb = { 132, 34, 255 };
    struct HSB_t hsb;

    RgbToHsb(rgb, &hsb);

    printf("RGB(%u,%u,%u) -> HSB(%f,%f,%f)\n", rgb.red, rgb.green, rgb.blue,
           hsb.hue, hsb.saturation, hsb.brightness);
    // prints: RGB(132,34,255) -> HSB(266.606354,0.866667,1.000000)

    return 0;
}