在 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 蓝色:0x0000ff00 是十进制 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 结构的主要内容,如果未能解决你的问题,请参考以下文章
Sass/Compass - 将 Hex、RGB 或命名颜色转换为 RGBA