如何从DWORD RGBA转换为int?

时间:2009-10-17 14:54:25

标签: c++

我必须将DWORD(无符号长)RGBA转换为四个int vars(R,G,B和A) 到目前为止,我有这个函数将4个int转换为DWORD:

unsigned long RGBA2DWORD(int iR, int iG, int iB, int iA)
{
    return ((iA << 24) | (iR << 16) | (iG << 8) | iB);
}

如何将其转换回来?

这样的东西
struct RGBA
{
    int R, G, B, A;
};

RGBA DWORD2RGBA(unsigned long dwColor)
{
    static RGBA tmp;
    //.......conversion process
    return tmp;
}

任何形式的帮助将不胜感激! :)

由于

4 个答案:

答案 0 :(得分:10)

如果我是你,我会在打包/解包功能中坚持使用乘法 - 加法运算。像这样的东西

unsigned long RGBA2DWORD(int iR, int iG, int iB, int iA)
{        
  return ((iA * 256 + iR) * 256 + iG) * 256 + iB;
}

具有对称解包功能

RGBA DWORD2RGBA(unsigned long dwColor)
{        
  RGBA tmp; /* why did you declare it static??? */

  tmp.B = dwColor % 256; dwColor /= 256;
  tmp.G = dwColor % 256; dwColor /= 256;
  tmp.R = dwColor % 256; dwColor /= 256;
  tmp.A = dwColor % 256; /* dwColor /= 256; */

  return tmp;
}

请注意,整个代码中只有一个“魔术常量”。

当然,如果您的外部规范是根据打包数据中的位模式编写的,那么基于位和移位操作的版本可能是首选的。仍然

unsigned long RGBA2DWORD(int iR, int iG, int iB, int iA)
{        
  return (((((iA << 8) + iR) << 8) + iG) << 8) + iB;
}

RGBA DWORD2RGBA(unsigned long dwColor)
{        
  RGBA tmp; /* why did you declare it static??? */

  tmp.B = dwColor & 0xFF; dwColor >>= 8;
  tmp.G = dwColor & 0xFF; dwColor >>= 8;
  tmp.R = dwColor & 0xFF; dwColor >>= 8;
  tmp.A = dwColor & 0xFF; /* dwColor >>= 8; */

  return tmp;
}

的“魔力常数”要少得多。

现在,您可以将重复动作/子表达式包装在宏或更好的内联函数中,并获得非常紧凑和可读的打包/解包器。

答案 1 :(得分:3)

如果您不介意为RGBA使用字节大小的整数,则可以使用union。 [编辑这是一种常用的方法,你不太可能找到一个不支持它的编译器,但严格来说(所以我被告知)这是一个非法的黑客攻击。在大多数情况下,更好的方法是进行数学或二进制转换,但我会留下我的答案的一半,因为它可以帮助读者理解当他们在真实中看到这种类型的代码时人们在做什么。世界]

union RGBA
{
    DWORD dword;
    unsigned char RGBA[4];
    struct RGBAstruct
    {
        unsigned char b;
        unsigned char g;
        unsigned char r;
        unsigned char a;
    }
};

然后您可以访问绿色组件:

RGBA colour;
int green = (int) colour.RGBA[2];

int green = (int) colour.RGBAstruct.g;

并以

的形式访问DWORD值
DWORD value = colour.dword;

如果您需要RGBA值为int值,或者希望使用转换方法,则需要使用按位运算符。

您正在对它们进行几乎的编码,但是您需要使用按位OR运算符|,而不是逻辑OR ||操作者:

DWORD value = (iA << 24) | (iR << 16) | (iG << 8) | iB;

向相反的方向前进:

int iA = (value >> 24) & 0xff;
int iR = (value >> 16) & 0xff;
int iG = (value >> 8) & 0xff;
int iB = (value) & 0xff;

答案 2 :(得分:2)

你可以反过来说:

iA = rgb&gt;&gt; 24; iR =(0x00FF0000&amp; rgb)&gt;&gt; 16; iG =(0x0000FF00&amp; rgb)&gt;&gt; 8; iB =(0x000000FF&amp; rgb);

答案 3 :(得分:1)

实际上,无符号长整数的RGBA部分应为:

int iR =(value)&amp; 0xFF的;
int iG =(value&gt;&gt; 8)&amp; 0xFF的;
int iB =(value&gt;&gt; 16)&amp; 0xFF的;
int iA =(值>&gt; 24)&amp; 0xff的;

并且整个问题是关于BGRA(根据问题的例子)而不是RGBA。