16位增强色RGB转换为24/32位真色彩

biBitCount=16 表示位图最多有65536种颜色。每个色素用16位(2个字节)表示。这种格式叫作高彩色,或叫增强型16位色,或64K色。它的情况比较复杂,当biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,最高的一位保留,设为0。这种格式也被称作555 16位位图。如果biCompression成员的值是BI_BITFIELDS,那么情况就复杂了,首先是原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。分别用于描述红、绿、蓝分量在16位中所占的位置。在Windows 95(或98)中,系统可接受两种格式的位域:555和565,在555格式下,红、绿、蓝的掩码分别是:0x7C00、0x03E0、0x001F,而在565格式下,它们则分别为:0xF800、0x07E0、0x001F。你在读取一个像素之后,可以分别用掩码“与”上像素值,从而提取出想要的颜色分量(当然还要再经过适当的左右移操作)。在NT系统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,它更多的被用于游戏软件)。
        RGB1、RGB4、RGB8都是调色板类型的RGB格式,在描述这些媒体类型的格式细节时,通常会在BITMAPINFOHEADER数据结构后面跟着一个调色板(定义一系列颜色)。它们的图像数据并不是真正的颜色值,而是当前像素颜色值在调色板中的索引。以RGB1(2色位图)为例,比如它的调色板中定义的两种颜色值依次为0x000000(黑色)和0xFFFFFF(白色),那么图像数据001101010111…(每个像素用1位表示)表示对应各像素的颜色为:黑黑白白黑白黑白黑白白白…。  
    RGB565使用16位表示一个像素,这16位中的5位用于R,6位用于G,5位用于B。程序中通常使用一个字(WORD,一个字等于两个字节)来操作一个像素。当读出一个像素后,这个字的各个位意义如下: 
          高字节                             低字节 
R   R   R   R   R   G   G   G           G   G   G   B   B   B   B   B 
可以组合使用屏蔽字和移位操作来得到RGB各分量的值: 

#define   RGB565_MASK_RED         0xF800 
#define   RGB565_MASK_GREEN     0x07E0 
#define   RGB565_MASK_BLUE       0x001F 
R   =   (wPixel   &   RGB565_MASK_RED)   > >   11;       //   取值范围0-31 
G   =   (wPixel   &   RGB565_MASK_GREEN)   > >   5;     //   取值范围0-63 
B   =     wPixel   &   RGB565_MASK_BLUE;                   //   取值范围0-31 

¨   RGB555是另一种16位的RGB格式,RGB分量都用5位表示(剩下的1位不用)。使用一个字读出一个像素后,这个字的各个位意义如下: 
          高字节                           低字节 
X   R   R   R   R   G   G               G   G   G   B   B   B   B   B               (X表示不用,可以忽略) 
可以组合使用屏蔽字和移位操作来得到RGB各分量的值: 

#define   RGB555_MASK_RED         0x7C00 
#define   RGB555_MASK_GREEN     0x03E0 
#define   RGB555_MASK_BLUE       0x001F 
R   =   (wPixel   &   RGB555_MASK_RED)   > >   10;       //   取值范围0-31 
G   =   (wPixel   &   RGB555_MASK_GREEN)   > >   5;     //   取值范围0-31 
B   =     wPixel   &   RGB555_MASK_BLUE;                   //   取值范围0-31 

¨   RGB24使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。注意在内存中RGB各分量的排列顺序为:BGR   BGR   BGR…。通常可以使用RGBTRIPLE数据结构来操作一个像素,它的定义为: 

typedef   struct   tagRGBTRIPLE   {   
    BYTE   rgbtBlue;         //   蓝色分量 
    BYTE   rgbtGreen;       //   绿色分量 
    BYTE   rgbtRed;           //   红色分量 
}   RGBTRIPLE; 

¨   RGB32使用32位来表示一个像素,RGB分量各用去8位,剩下的8位用作Alpha通道或者不用。(ARGB32就是带Alpha通道的RGB32。)注意在内存中RGB各分量的排列顺序为:BGRA   BGRA   BGRA…。通常可以使用RGBQUAD数据结构来操作一个像素,它的定义为: 

typedef   struct   tagRGBQUAD   { 
    BYTE         rgbBlue;             //   蓝色分量 
    BYTE         rgbGreen;           //   绿色分量 
    BYTE         rgbRed;               //   红色分量 
    BYTE         rgbReserved;     //   保留字节(用作Alpha通道或忽略) 
}   RGBQUAD; 


处理16bit的RGB图像并保存为24bit的像素格式时,可参照如下处理方式
/// @brief 多字节位移要注意大端小端问题,x86默认小端
switch(d3dFormat)
{
case D3DFMT_R5G6B5:
#define   RGB565_MASK_RED 0xF800 
#define   RGB565_MASK_GREEN 0x07E0 
#define   RGB565_MASK_BLUE 0x001F 
r = ((wPix16 & RGB565_MASK_RED) >> 11) * (256 / 32);  ///< 取值范围0-31,线性放大
g = ((wPix16 & RGB565_MASK_GREEN) >> 5) * (256 / 64);  ///< 取值范围0-63,线性放大
b = (wPix16 & RGB565_MASK_BLUE) * (256 / 32);            ///< 取值范围0-31,线性放大
memcpy(lpDst, &b, 1);
memcpy(lpDst + 1, &g, 1);
memcpy(lpDst + 2, &r, 1);
uiOffset = 2;
break;

case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
#define   RGB555_MASK_RED 0x7C00
#define   RGB555_MASK_GREEN 0x03E0
#define   RGB555_MASK_BLUE 0x001F
r = ((wPix16 & RGB555_MASK_RED) >> 10) * (256 / 32);  ///< 取值范围0-31,线性放大
g = ((wPix16 & RGB555_MASK_GREEN) >> 5) * (256 / 32);  ///< 取值范围0-31,线性放大
b = (wPix16 & RGB555_MASK_BLUE) * (256 / 32);            ///< 取值范围0-31,线性放大
memcpy(lpDst, &b, 1);
memcpy(lpDst + 1, &g, 1);
memcpy(lpDst + 2, &r, 1);
uiOffset = 2;
break;

case D3DFMT_A4R4G4B4:
case D3DFMT_A8R3G3B2:
case D3DFMT_X4R4G4B4:
case D3DFMT_L16:
case D3DFMT_A8L8:
// 参照上面同理处理
uiOffset = 2;
break;
}

你可能感兴趣的:(数字图像处理)