今天编一个显示位图的程序,使用了StretchDIBits函数,它的倒数第二个参数是BITMAPINFO结构体指针。BITMAPINFO结构体是这样定义的:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO; 它的第一个参数是位图信息头,第二个参数让我很难理解。我查了下MSDN,它这样解释的:The BITMAPINFO structure defines the dimensions and color information for a DIB. typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
Members
bmiHeader
Specifies a BITMAPINFOHEADER structure that contains information about the dimensions of color format.
. bmiColors
The bmiColors member contains one of the following:
An array of RGBQUAD. The elements of the array that make up the color table.
An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of bmiColors is allowed for functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, they must also call the following bitmap functions:
CreateDIBitmap CreateDIBPatternBrush CreateDIBSection The iUsage parameter of CreateDIBSection must be set to DIB_PAL_COLORS. The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure. The colors in the bmiColors table appear in order of importance. For more information, see the Res section.Res
A DIB consists of two distinct parts: a BITMAPINFO structure describing the dimensions and colors of the bitmap, and an array of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeroes to end on a LONG data-type boundary. If the height of the bitmap is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If the height is negative, the bitmap is a top-down DIB and its origin is the upper left corner. A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header. Packed bitmaps are referenced by a single pointer. For packed bitmaps, the biClrUsed member must be set to an even number when using the DIB_PAL_COLORS mode so that the DIB bitmap array starts on a DWORD boundary. Note The bmiColors member should not contain palette indexes if the bitmap is to be stored in a file or transferred to another application. Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain explicit RGB values. 我看了半天,也没明白bmiColors[1]有什么用。我唯一明确的一点是bmiColors[1]所包含的信息并没有存在位图文件,在传输图像时也不需要传输。
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO; 它的第一个参数是位图信息头,第二个参数让我很难理解。我查了下MSDN,它这样解释的:The BITMAPINFO structure defines the dimensions and color information for a DIB. typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
Members
bmiHeader
Specifies a BITMAPINFOHEADER structure that contains information about the dimensions of color format.
. bmiColors
The bmiColors member contains one of the following:
An array of RGBQUAD. The elements of the array that make up the color table.
An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of bmiColors is allowed for functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, they must also call the following bitmap functions:
CreateDIBitmap CreateDIBPatternBrush CreateDIBSection The iUsage parameter of CreateDIBSection must be set to DIB_PAL_COLORS. The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure. The colors in the bmiColors table appear in order of importance. For more information, see the Res section.Res
A DIB consists of two distinct parts: a BITMAPINFO structure describing the dimensions and colors of the bitmap, and an array of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeroes to end on a LONG data-type boundary. If the height of the bitmap is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If the height is negative, the bitmap is a top-down DIB and its origin is the upper left corner. A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header. Packed bitmaps are referenced by a single pointer. For packed bitmaps, the biClrUsed member must be set to an even number when using the DIB_PAL_COLORS mode so that the DIB bitmap array starts on a DWORD boundary. Note The bmiColors member should not contain palette indexes if the bitmap is to be stored in a file or transferred to another application. Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain explicit RGB values. 我看了半天,也没明白bmiColors[1]有什么用。我唯一明确的一点是bmiColors[1]所包含的信息并没有存在位图文件,在传输图像时也不需要传输。
16位色深以上的图片就没有了。
bmiColors[1]只是一个RGBQUAD,RGBQUAD结构体定义如下
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD; 就是说它只能存储一个RGB颜色。像256色的图片,bmiColors[1]怎么能存贮它的颜色表信息呢?难道你说的是单色图像?
那它在程序怎么表示RGB颜色呢?不完整结构何解啊?
1:必须是结构的最后成员
2:有些编译器 只要【】,1都可以不要。
bmiColors[1]使用时要根据bmp中的颜色数来确定到底有多少个。
LPBITMAPINFOHEADER pBi;
RGBQUAD *pRgb;
pBf=(LPBITMAPFILEHEADER) pBuffer;
pBi=(LPBITMAPINFOHEADER )(pBuffer +sizeof(BITMAPFILEHEADER));
pRgb=(RGBQUAD*)(pBuffer+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
//
if(pBi->biClrUsed==0) NumColors=1<<pBi->biBitCount;
//
LineBytes=pBi->biWidth;
//
pImgData=pBuffer+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD);
大侠,例子不太对吧,没看到用到了bmiColors这个数据成员。上面的代码我基本清楚,先读取文件信息头,再读位图信息头,再读调色板数据,最后读图像数据。
NumColors不就是使用的RGB颜色的个数吗?和BITMAPINFO的数据成员bmiColors怎么联系起来的呢?不解。
NumColors*sizeof(RGBQUAD);就是所谓的bmiColors[],因为bmiColors个数不定,直接引用没意义,除非你知道[i]
明白,图像数据的位置 = 文件指针偏移(文件头大小+位图信息头+ RGB颜色个数*调色板结构大小)。我的意思是在程序中都没直接用到bmiColors这个数据成员,那要它何用呢?
16位色深以上的图片就没有了。
bmiColors[1]一般存储了它的颜色表信息?怎么存贮呢?
BOOL CDib::MakePalette()
{
// makes a logical palette (m_hPalette) from the DIB's color table
// this palette will be selected and realized prior to drawing the DIB
if(m_nColorTableEntries == 0) return FALSE;
if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
TRACE("CDib::MakePalette -- m_nColorTableEntries = %d\n", m_nColorTableEntries);
LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +
m_nColorTableEntries * sizeof(PALETTEENTRY)];
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = m_nColorTableEntries;
LPRGBQUAD pDibQuad = (LPRGBQUAD) m_lpvColorTable;
for(int i = 0; i < m_nColorTableEntries; i++) {
pLogPal->palPalEntry[i].peRed = pDibQuad->rgbRed;
pLogPal->palPalEntry[i].peGreen = pDibQuad->rgbGreen;
pLogPal->palPalEntry[i].peBlue = pDibQuad->rgbBlue;
pLogPal->palPalEntry[i].peFlags = 0;
pDibQuad++;
}
m_hPalette = ::CreatePalette(pLogPal);
delete pLogPal;
return TRUE;
}
// 例子:
RGBQUAD color_table[16]={
{0, 0, 0, 0}, //0
{0, 0,128, 0}, //1
{0,128, 0, 0}, //2
{0,128,128, 0}, //3
{128,0, 0, 0}, //4
{128,0,128, 0}, //5
{128,128,0, 0}, //6
{128,128,128,0}, //7
{192,192,192,0}, //8
{0, 0, 255,0}, //9
{0,255, 0, 0}, //10
{0,255,255, 0}, //11
{255, 0,0, 0}, //12
{255, 0,255,0}, //13
{255,255, 0,0}, //14
{255,255,255,0}}; //15
NumColors*sizeof(RGBQUAD)和bmiColors关联不上,那它存在的意义是什么?
调色板数据不是保存在bmiColors的。
下面用二进制表示下你就懂了:
0000 0000 0000 0000 一共16位
如果5位存红,6位存绿,5位存蓝,那么就要这样分
0000 0(红)000 000(绿)0 0000(蓝)
这时 bmiColor就起作用了,
bmiColor[0] = 1111 1000 0000 0000 // 红色
bmiColor[1] = 0000 0111 1110 0000 // 绿色
bmiColor[2] = 0000 0000 0001 1111 // 蓝色
然后系统会将上面的3个分别与你数据区的数据做&运算,这样就能分别把每种颜色提取出来了