今天编一个显示位图的程序,使用了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]所包含的信息并没有存在位图文件,在传输图像时也不需要传输。

解决方案 »

  1.   

    像256色的图片,bmiColors[1]一般存储了它的颜色表信息,像素颜色的还原都是根据这张表里记录的颜色信息来还原的。
    16位色深以上的图片就没有了。
      

  2.   


       bmiColors[1]只是一个RGBQUAD,RGBQUAD结构体定义如下
    typedef struct tagRGBQUAD {
            BYTE    rgbBlue;
            BYTE    rgbGreen;
            BYTE    rgbRed;
            BYTE    rgbReserved;
    } RGBQUAD;    就是说它只能存储一个RGB颜色。像256色的图片,bmiColors[1]怎么能存贮它的颜色表信息呢?难道你说的是单色图像?
      

  3.   

    bmiColors[1]表示有这个成员,但实际不一定是1,这叫不完整结构。
      

  4.   


        那它在程序怎么表示RGB颜色呢?不完整结构何解啊?
      

  5.   

    对于256色的位图,R、G、B三个值是一样的,而24位图,它是没有颜色表的。 
      

  6.   

    至于bmiColors[1],"RGBQUAD   bmiColors[1];"它是一个对象。所以我认为它并不是说储存一种颜色
      

  7.   

    不完整结构
    1:必须是结构的最后成员
    2:有些编译器 只要【】,1都可以不要。
    bmiColors[1]使用时要根据bmp中的颜色数来确定到底有多少个。
      

  8.   

    LPBITMAPFILEHEADER pBf;
    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);
      

  9.   


       大侠,例子不太对吧,没看到用到了bmiColors这个数据成员。上面的代码我基本清楚,先读取文件信息头,再读位图信息头,再读调色板数据,最后读图像数据。
      

  10.   

    if(pBi->biClrUsed==0) NumColors=1<<pBi->biBitCount
      

  11.   


        NumColors不就是使用的RGB颜色的个数吗?和BITMAPINFO的数据成员bmiColors怎么联系起来的呢?不解。
      

  12.   

    pImgData=明白了?
    NumColors*sizeof(RGBQUAD);就是所谓的bmiColors[],因为bmiColors个数不定,直接引用没意义,除非你知道[i]
      

  13.   


        明白,图像数据的位置 = 文件指针偏移(文件头大小+位图信息头+ RGB颜色个数*调色板结构大小)。我的意思是在程序中都没直接用到bmiColors这个数据成员,那要它何用呢?
      

  14.   

    像256色的图片,bmiColors[1]一般存储了它的颜色表信息,像素颜色的还原都是根据这张表里记录的颜色信息来还原的。
    16位色深以上的图片就没有了。 
     
      

  15.   


        bmiColors[1]一般存储了它的颜色表信息?怎么存贮呢?
      

  16.   

    参考:
    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
      

  17.   


         NumColors*sizeof(RGBQUAD)和bmiColors关联不上,那它存在的意义是什么?
      

  18.   

    当一个bmp的color数知道后,可以从bmiColors[]得到颜色,然后MakePalette,
      

  19.   


       调色板数据不是保存在bmiColors的。
      

  20.   

    调色板数据就是使用bmiColors的
      

  21.   

    举个例子,16位的BMP,就要用16个bits(两个字节)保存RGB三种颜色,那么这三种颜色该怎么分配储存呢?
    下面用二进制表示下你就懂了:
    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个分别与你数据区的数据做&运算,这样就能分别把每种颜色提取出来了
      

  22.   

    因为16位的颜色方案有很多,刚刚说的565(5红6绿5蓝)是常用的一种,另外还有555+0位等等,如果是灰度图片就把bmiColor[]都设成 0xFFFF (二进制 1111 1111 1111 1111)这样三种颜色必然都会相等就是灰色了