在 C 中从 HEX 颜色转换为 RGB 结构

Posted

技术标签:

【中文标题】在 C 中从 HEX 颜色转换为 RGB 结构【英文标题】:Convert from HEX color to RGB struct in C 【发布时间】:2011-04-13 00:53:42 【问题描述】:

如何仅使用 C 库(不使用 C++ 或模板)将颜色 HEX 代码转换为纯 C 中的 RGB? RGB结构可能是这样的:

typedef struct RGB 
    double r;
    double g;
     double b;
 RGB1;

我正在寻找的函数应该返回 RGB1。

【问题讨论】:

我不确定我是否理解这个问题。我相信将事物标记为代码和/或在问题的关键位置插入换行符可能有助于使人们更容易阅读(并因此回答)问题。 【参考方案1】:

RGB 值可以通过 0xRRGGBB 以整数形式存储。例子:

红色:0xff0000 绿色:0x00ff00 蓝色:0x0000ff

00 是十进制 0 的十六进制,而 ff 是 255。0 对应于 0.0,255 对应于 1.0。 (实际上你没有指定范围是多少。我假设是 0.0 到 1.0。)

因此,根据上述假设,您需要提取每个分量并除以 255。因为这听起来很像家庭作业问题,所以我将向您展示如何做红色分量。

int hex = 0x123456;
c.r = ((hex >> 16) & 0xff) / 255.0;

每个十六进制数字占用 4 位。因此向右移动 16 位(将所有内容向右移动 4 位)以使 0xRRGGBB 变为 0xRR。现在你有了红色组件。 (以防万一整数中有更高的数据,您可以通过& 0xff 屏蔽数据来摆脱它。)

如果您正在处理字符串"#FFFFFF",那么您首先必须将其转换为整数才能使上述操作生效。

【讨论】:

【参考方案2】:

假设您的十六进制值是 32 位“int”类型,并且我们使用上述 RGB 结构,那么可能会执行以下操作:

struct RGB colorConverter(int hexValue)

  struct RGB rgbColor;
  rgbColor.r = ((hexValue >> 16) & 0xFF) / 255.0;  // Extract the RR byte
  rgbColor.g = ((hexValue >> 8) & 0xFF) / 255.0;   // Extract the GG byte
  rgbColor.b = ((hexValue) & 0xFF) / 255.0;        // Extract the BB byte

  return rgbColor; 

【讨论】:

有点扯掉@konforce 给出的答案,不是吗? 不。那里也有用于字符串处理的代码,但是 konforce 关于这可能是一个家庭作业问题的观点是一个很好的问题。因此,我编辑了这个答案,使其更像上面发布的一个 kon。 hexValue 应该是 unsigned int 类型吗?我认为 &0xFF 取消了算术移位,但是像 0xFFFFFF 这样的值在传入时不会导致溢出吗? 'unsigned int' 可能会更好一些。也就是说,在这种情况下,这并不重要,因为 RRGGBB 适合 24 位,而“int”类型(非常普遍)长度为 32 位。这个答案确实假设 RRGGBB 位以某种方式存储在 int 中,尽管......所以请注意。【参考方案3】:

我猜 RGB 在某些系统上可以存储为 0xRRGGBB,但在 Windows 中它实际上存储为 0xBBGGRR(请参阅http://msdn.microsoft.com/en-us/library/windows/desktop/dd183449)。正如文章中提到的,已经有 GetRValue、GetGValue 和 GetBValue 宏可用。

【讨论】:

【参考方案4】:

如果十六进制码是字符串,可以这样解析

char *str = "0000FF";
int r, g, b;
sscanf(str, "%02x%02x%02x", &r, &g, &b);

这是整数,而不是双精度数。还要检查 sscanf 是否返回 3,即读取的项目数。

【讨论】:

如果你想解析成unsigned short值,请使用格式字符串"%2hx%2hx%2hx" 我使用 sscanf(str.c_str(), "%02hhx%02hhx%02hhx", &r, &g, &b);std::string 将其解析为 unsigned char 值, 我对 Tor 的回答赞不绝口!优雅的解决方案。【参考方案5】:

我知道这已经很老了,但我还想提供一个没有任何位运算的联合解决方案。

union Color

    unsigned int hex;
    struct  unsigned char b, g, r; ;
;

通过这种方式,您可以轻松地从 HEX 转换为 RGB,从 RGB 转换为 HEX。

union Color hex;
hex.hex = 0x07C73C;

union Color rgb;
rgb.r = 7;
rgb.g = 199;
rgb.b = 60;

printf("RGB(%d, %d, %d), HEX(%06x)", hex.r, hex.g, hex.b, rgb.hex);

输出:

RGB(7, 199, 60), HEX(07c73c)

要映射 0.0 到 1.0 范围内的值,只需将其除以 255.0 :)

编辑: 以上代码^^仅在Little-Endian CPU架构下支持,更好的方式是check what endianness does the system runs on。

然后你可以检查字节序来定义结构变量的顺序。

union Color

    unsigned int hex;

#if IS_BIG_ENDIAN
    struct  unsigned char a, r, g, b; ;
#else
    struct  unsigned char b, g, r, a; ;
#endif
;

此代码还支持 RGBA 中的 alpha(透明度)。

【讨论】:

很好的答案,但您应该检查字节顺序以确保答案完整。参考***.com/q/18863913/8339821。 好点,我会做一些测试并更新答案。 太好了,请在更新时发表评论。 mb 你会得到一个赞成票;) @yvw 我更新了支持两种字节序的答案,我非常不确定 Windows 系统是否只有小字节序,最终使用了 CPU 检查宏。 BSD 似乎有 <endian.h><sys/endian.h>。其他系统可能根本没有标头。

以上是关于在 C 中从 HEX 颜色转换为 RGB 结构的主要内容,如果未能解决你的问题,请参考以下文章

使用来自背景颜色的变量从 rgb 转换为 hex

Sass/Compass - 将 Hex、RGB 或命名颜色转换为 RGBA

将 RGBA 转换为 HEX

如何为Android转换器中的MvxColor指定Hex或RGB颜色

JavaScript RGB颜色与hex16进制转换

JavaScript RGB颜色与hex16进制转换