我现在在内存里面构建了一个完整的bmp,包括文件头,信息头,调色板,以及数据,我想把它显示出来,应该怎么写程序啊?
    我看了好几个显示bmp的程序,都是用loadbitmap加载的啊,我不知道不从文件加载应该怎么得到位图句柄,更应该如何显示呢?
帮忙啊,急啊!

解决方案 »

  1.   

    最近我刚刚填写了一次,给你参考一下
    hbp = CreateDIBitmap(h_DC, 
                    (BITMAPINFOHEADER *)binfo, 
                    CBM_INIT, 
                    (LPSTR)pDate, 
                    (LPBITMAPINFO)binfo, 
                    DIB_RGB_COLORS );
      

  2.   

    我不太清楚BITMAPINFO里面是怎么管理RGBQUAD的!
      

  3.   

    借地方说个话,
    typedef struct tagBITMAPINFO { 
      BITMAPINFOHEADER bmiHeader; 
      RGBQUAD          bmiColors[1]; 
    } BITMAPINFO, *PBITMAPINFO; 
    BITMAPINFO的结构是这样的,为什么
    BITMAPINFO bitmapinfo;
    bitmapinfo.bmiColors = new RGBQUAD[3];
    编译通不过?

    E:\chuanqi\viewWil2\WHWilImageData.cpp(67) : error C2440: '=' : cannot convert from 'struct tagRGBQUAD *' to 'struct tagRGBQUAD [1]'
    我要怎么才能指定多个调色板呢?
      

  4.   

    我通常是这样搞的
    首先要计算调色版的大小
    然后加上BITMAPINFOHEADER的大小
    顺便再扩大20几个字节
    申请一块内存(有的时候把图像数据段的也申请在一起也是可以的)
    unsigned char *p=(unsigned char *)malloc(sizeof(BITMAPINFOHEADER)+platSize+....)
    然后用(BITMAPINFOHEADER*)p->....这样可以把头填好
    然后用(p+sizeof(BITMAPINFOHEADER))做指针填写调色板(创建好了,往里复制)
    这样处理以后
    (BITMAPINFO*)p,
    你再看这个p是不是就符合tagBITMAPINFO 的定义了?
      

  5.   

    楼主你说没有调色板,没有调色板你的数据怎么得到的呢?从24位图转过来的?
    mfc中有CPalette这个类,可以创建调色板,你自己看看吧
      

  6.   

    16Bit没有调色板的~~获取数据,CFile直接搞定..
      

  7.   

    噢,晕,看楼了,不是16Bit位图..却是16位数据的调色板(RGBQUAD 保存为16位?),倒~~~
      

  8.   

    是16bit的图,这个调色板是rgb的掩码啊,不管是不是调色板吧,反正它的位置在bitmapfileinfoheader和图片数据之间,就是调色板的位置啊!
      

  9.   

    从文件加载要用LoadImage函数,正好满足你的要求,看一下MSDN,也有例子
      

  10.   

    调色板就是比色卡
    比如256色的(就是8位的),可以知道最多一共有256种颜色色
    比如数据段中存放有0xA1,x0xB5,x0FF这样的数据
    256色用每个字节表示一个像素
    0xA1,表示这个点得像素的颜色和调色板的第0xA1项是相同的
    调色板的数据都是这样的(r,g,b,保留位(不用考虑))
    这样我们就可以用一个8位字节描述一个真彩色的点了
    当然,虽然失真彩色的,正张图片中的所有像素的色彩总和只有256中
    因为通常一张bmp中所有得像素色彩不可能用到真彩的所有颜色,再加上很多情况下一些点是相近的(肉眼无法分辨),所以各种压缩才有意义
      

  11.   

    HBITMAP CBtn::LoadBitmapFromFile(HINSTANCE hInst, LPTSTR szFileName)
    {
      BITMAP  bm;   HBITMAP phBitmap = NULL;
       phBitmap = (HBITMAP)LoadImage( hInst, szFileName, IMAGE_BITMAP, 0, 0,
                   LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
       if( phBitmap == NULL )
         return FALSE;   GetObject(phBitmap, sizeof(BITMAP), &bm );
       if( ( bm.bmBitsPixel * bm.bmPlanes ) <= 8 )
       {
       HDC           hMemDC;
       HBITMAP       hOldBitmap;
       hMemDC = CreateCompatibleDC( NULL );
       hOldBitmap = (HBITMAP)SelectObject( hMemDC, phBitmap );    SelectObject( hMemDC, hOldBitmap );
       DeleteDC( hMemDC );
       }
       else   
       {
       HDC    hRefDC;    hRefDC = ::GetDC( NULL );
        ::ReleaseDC( NULL, hRefDC );
       }
       return phBitmap;
    }
      

  12.   

    如果是16BitBmp(非调色板位图),像素值保存为16位(真彩色是24位3个字节)的吧..
    如果是16Bit的调色板位图,那好办了,位数据只是调色板的索引,把16Bit RGBQUAD转换为24BIT RGBQUAD并实现PALETTE,然后就可以直接显示了..TNND,16Bit是如下所保存的?
    一个WORD:
    0x0bbbbbgggggrrrrr <= 5位保存一个r、g、b值?
      

  13.   

    Wrong..是一个WORD:
    0bbbbbgggggrrrrr
      

  14.   

    原来我都编好函数来着,找了半天没找到http://expert.csdn.net/Expert/topic/2070/2070026.xml?temp=.8021509
    看看这个有没有帮助
      

  15.   

    楼主,原来我碰见过这种问题,实现的很丑陋,把fileheader,infoheader,rgbquad,有效数据都写到一个临时文件里面去了,然后再用loadimage取进来的,实在很ugly啊:)
    我也是来这里学习的!
    另外我知道16位的掩码调色板是
    bbbbbggggggrrrrr这种16位数据的掩码!
    好象三个分别是
    F8000000
    007D0000
    00001F00
      

  16.   

    楼上的,应该怎么弄啊?确实不知道,我也看了不少的资料,但要不是从文件中来的,要不用setdlbbitstodevice,就是没有讲怎么设置调色板的!
      

  17.   

    The CreateDIBSection function creates a DIB that applications can write to directly. The function gives you a pointer to the location of the bitmap bit values. You can supply a handle to a file-mapping object that the function will use to create the bitmap, or you can let the system allocate the memory for the bitmap.HBITMAP CreateDIBSection(
      HDC hdc,                 // handle to DC
      CONST BITMAPINFO *pbmi,  // bitmap data
      UINT iUsage,             // data type indicator
      VOID **ppvBits,          // bit values
      HANDLE hSection,         // handle to file mapping object
      DWORD dwOffset           // offset to bitmap bit values
    );
      

  18.   

    SURE...CreateDIBSection() 
    then
    StretchDIBits()
      

  19.   

    楼上的楼上,我看了CreateDIBSection的msdn的帮助,我不知道CONST BITMAPINFO *pbmi中的RGBQUAD[1]怎么设置啊,我明明有三个调色板啊!
      

  20.   

    如果只有数据没有一点关于调色板的信息,那么是完全没有办法重建调色板的
    总要知道是从什么文件来的,
    或者是从什么色的数据转化来的
    或者是从哪个DC存下来的因为有人甚至通过改变调色板来改变图像效果,你说调色板靠得住么??
    我曾经在把24位位图象256位图压缩的时候自己创建了一个调色板,愣给每个RGBQUAD付的值
    不知道
    http://www.vckbase.com/code/listcode.asp?mclsid=7&sclsid=703
    这个试我以前做的例子,不过没有代码了,只有库,这里面的调色板就是手动创建的
      

  21.   

    调色板和显示效果可以得到数据GetDIBits(..)
    调色板和数据可以得到显示效果SelectObject(..)
    只有数据既不能得到调色板,也不能得到显示效果
      

  22.   

    单只有数据,也能显示..
    自己构造BITMAPINFO~~
      

  23.   

    RGBQUAD[1]是为了便于使用数组下标访问后面的可能有的调色板信息,但是对于不同的位图,调色板的数目可能不同。调色板的数目可以参见BITMAPINFOHEADER的说明
      

  24.   

    调色板我知道
    就是 lsaturn(土星-站了一晚) 说的
    F8000000
    007D0000
    00001F00
    是rgb的掩码,
     akiy(winexec)你怎么能连续回复4次呢?星星的原因?
    我整理下我的程序,大家来看看吧!
      

  25.   

    typedef struct tagBitmapData
    {
    BITMAPFILEHEADER BitmapFilehead;
    BITMAPINFOHEADER BitmapInfo;
    RGBQUAD quadRGB[3];
    WORD* pwEffectData;
    }BITMAPDATA, *LPBITMAPDATA;
    LPBITMAPDATA m_lpstFinalBitmap;m_lpstFinalBitmap->BitmapFilehead.bfType =  ((WORD)  ('M'  <<  8)    |  'B');            //  is  always  "BM"  
    m_lpstFinalBitmap->BitmapFilehead.bfSize =  m_lpstNewCurrWilImageInfo->shWidth * m_lpstNewCurrWilImageInfo->shHeight * 2 + 0x42;  
    m_lpstFinalBitmap->BitmapFilehead.bfReserved1 =  0;            //保留字  
    m_lpstFinalBitmap->BitmapFilehead.bfReserved2 =  0;            //保留字  
    m_lpstFinalBitmap->BitmapFilehead.bfOffBits   =  0x42;m_lpstFinalBitmap->BitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
    m_lpstFinalBitmap->BitmapInfo.biWidth = m_lpstNewCurrWilImageInfo->shWidth;
    m_lpstFinalBitmap->BitmapInfo.biHeight = m_lpstNewCurrWilImageInfo->shHeight;
    m_lpstFinalBitmap->BitmapInfo.biPlanes = 1;
    m_lpstFinalBitmap->BitmapInfo.biBitCount = 16;
    m_lpstFinalBitmap->BitmapInfo.biCompression =BI_BITFIELDS;
    m_lpstFinalBitmap->BitmapInfo.biSizeImage = m_lpstNewCurrWilImageInfo->shWidth * m_lpstNewCurrWilImageInfo->shHeight * 2;
    m_lpstFinalBitmap->BitmapInfo.biXPelsPerMeter = 0;
    m_lpstFinalBitmap->BitmapInfo.biYPelsPerMeter = 0;
    m_lpstFinalBitmap->BitmapInfo.biClrUsed = 0;
    m_lpstFinalBitmap->BitmapInfo.biClrImportant =0;m_lpstFinalBitmap->quadRGB[0].rgbBlue = 0;
    m_lpstFinalBitmap->quadRGB[0].rgbGreen = 0xF8;
    m_lpstFinalBitmap->quadRGB[0].rgbRed = 0;
    m_lpstFinalBitmap->quadRGB[0].rgbReserved = 0;
    m_lpstFinalBitmap->quadRGB[1].rgbBlue = 0xE0;
    m_lpstFinalBitmap->quadRGB[1].rgbGreen = 0x07;
    m_lpstFinalBitmap->quadRGB[1].rgbRed = 0;
    m_lpstFinalBitmap->quadRGB[1].rgbReserved = 0;
    m_lpstFinalBitmap->quadRGB[2].rgbBlue = 0x1F;
    m_lpstFinalBitmap->quadRGB[2].rgbGreen = 0;
    m_lpstFinalBitmap->quadRGB[2].rgbRed = 0;
    m_lpstFinalBitmap->quadRGB[2].rgbReserved = 0;m_lpstFinalBitmap->pwEffectData我已经给它赋上正确的值了,它指向有效的数据!上面的是对的,我受lsaturn(土星-站了一晚)的启发,把上面的一股脑写到一个bmp文件里面去显示出来的图象是正确的,但是直接在内存里面应该怎样使它显示呢?
      

  26.   

    开个大内存 binfo,把所有数据(不要fileinfoheader)一骨脑复制倒这块内存中
    然后
    HBITMAP hbp;
    hbp = CreateDIBitmap(h_DC, 
                    (BITMAPINFOHEADER *)binfo, 
                    CBM_INIT, 
                    (LPSTR)pDate, 
                    (LPBITMAPINFO)binfo, 
                    DIB_RGB_COLORS );
      

  27.   

    pDate=(LPSTR)(binfo+sizeof(BITMAPINFOHEADER)+platSize(调色板大小))
    再不行发给我
    [email protected]
      

  28.   

    的倒hbp以后你该会乐吧?
    坛子里说这个得贴都没数了
      

  29.   

    可否发张16Bit的bmp给偶?
    [email protected]
      

  30.   

    偶试过ok,用来打开row数据:
    ==========================================================
    typedef struct {
        BITMAPINFOHEADER bmiHeader;       //位图信息头
        RGBQUAD          bmiColors[3];    //颜色表
        } BMINFO16BIT;//自己包装 CFile file;
    if(!file.Open(str,CFile::modeRead))
        {
    AfxMessageBox("File cannot open..");
    return;
    }
    BYTE a[256*192*2];
    file.Read(a,256*192*2);
    file.Close();
    bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bminfo.bmiHeader.biWidth = 256;
        bminfo.bmiHeader.biHeight = 192;
        bminfo.bmiHeader.biPlanes = 1;
        bminfo.bmiHeader.biBitCount = 16;
        bminfo.bmiHeader.biCompression = BI_BITFIELDS;
        bminfo.bmiHeader.biSizeImage = 256 * 192 * 2;
        bminfo.bmiHeader.biXPelsPerMeter = 0;
        bminfo.bmiHeader.biYPelsPerMeter = 0;
        bminfo.bmiHeader.biClrUsed = 0;
        bminfo.bmiHeader.biClrImportant =0;    bminfo.bmiColors[0].rgbBlue = 0;
        bminfo.bmiColors[0].rgbGreen = 0xF8;
        bminfo.bmiColors[0].rgbRed = 0;
        bminfo.bmiColors[0].rgbReserved = 0;
        bminfo.bmiColors[1].rgbBlue = 0xE0;
        bminfo.bmiColors[1].rgbGreen = 0x07;
        bminfo.bmiColors[1].rgbRed = 0;
        bminfo.bmiColors[1].rgbReserved = 0;
        bminfo.bmiColors[2].rgbBlue = 0x1F;
        bminfo.bmiColors[2].rgbGreen = 0;
        bminfo.bmiColors[2].rgbRed = 0;
        bminfo.bmiColors[2].rgbReserved = 0;    CClientDC dc(this);
        void *pBits;
        HBITMAP hbitmap = CreateDIBSection(dc.m_hDC,
                                           (const BITMAPINFO *)&bminfo,
                                            DIB_RGB_COLORS,
                                           (VOID **)&pBits,
                                           NULL,
                                           0); memcpy(pBits,a,256*192*2);
        GdiFlush();
        StretchDIBits(dc.m_hDC,0,0,bminfo.bmiHeader.biWidth,
                      bminfo.bmiHeader.biHeight,0,0,bminfo.bmiHeader.biWidth,
                      bminfo.bmiHeader.biHeight,pBits,(BITMAPINFO *)&bminfo,
                      DIB_RGB_COLORS,SRCCOPY);=============================================================================以上随便乱写的,可以显示row数据(为16bitbmp),bmp应该一样的吧
      

  31.   

    可以不用HBITMAP就显示图象的HANDLE hDrawDib = DrawDibOpen();
    HDC hDC = GetDC(hWnd);
    DrawDibDraw(hDrawDib,hDC,0,0,width,height,&(m_lpstFinalBitmap->BitmapInfo),m_lpstFinalBitmap->pwEffectData,0,0,width,height,DDF_HALFTONE);
    ReleaseDC(hWnd,hDC);
    DrawDibClose(hDrawDib);
    必须包含<vfw.h>和winmm.lib,vfw32.lib
      

  32.   

    wrong,是raw数据,sorry..
    并非灌水呀~~
    kaka..
      

  33.   

    偶也没用HBITMAP啊,只是StretchDIBits(),用DrawDIBDraw()麻烦..
    Raw数据都行,没理由DIB不行的,TNND..
      

  34.   

    HBITMAP hBitmap;
    char* binfo;
    binfo = (char*)malloc(sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD) + 
    sizeof(WORD) * m_pwImage->m_lpstNewCurrWilImageInfo->shWidth
    * m_pwImage->m_lpstNewCurrWilImageInfo->shHeight);
    memcpy(binfo, &m_pwImage->m_lpstFinalBitmap->BitmapInfo, sizeof(BITMAPINFOHEADER));
    memcpy(binfo + sizeof(BITMAPINFOHEADER), m_pwImage->m_lpstFinalBitmap->quadRGB, 3 * sizeof(RGBQUAD));
    memcpy(binfo + sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD), m_pwImage->m_lpstFinalBitmap->pwEffectData, sizeof(WORD) * m_pwImage->m_lpstNewCurrWilImageInfo->shWidth * m_pwImage->m_lpstNewCurrWilImageInfo->shHeight);
    hBitmap = CreateDIBitmap(hSrcDC, 
    (BITMAPINFOHEADER *)binfo, 
    CBM_INIT, 
    (LPSTR)binfo, 
    (LPBITMAPINFO)binfo, 
    DIB_RGB_COLORS );
    显示出来一团糟!
      

  35.   

    搞掂啦!kaka...
    我把代码贴这,可能比较乱,sorry~~~
    =================================================================================
    void CMy16BitView::showDIB()
    {
    CMy16BitDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc); CString str;
    str = pDoc->GetPathName();
    CFile file;
    if(!file.Open(str,CFile::modeRead))
        {
    AfxMessageBox("File cannot open..");
    return;
    }
    BITMAPFILEHEADER bmfh;
    file.Read(&bmfh,sizeof(BITMAPFILEHEADER));
    BITMAPINFOHEADER bmih;
    file.Read(&bmih,sizeof(BITMAPINFOHEADER));
    DWORD m_BitLen = bmfh.bfSize - bmfh.bfOffBits;
    DWORD FileOffset = file.GetPosition();
    BYTE *Bits =  (BYTE *)malloc(m_BitLen);
    file.Seek(FileOffset+bmfh.bfOffBits,CFile::begin);
    file.ReadHuge(Bits,m_BitLen);

    //file.Close();
    bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bminfo.bmiHeader.biWidth = bmih.biWidth;
        bminfo.bmiHeader.biHeight = bmih.biHeight;
        bminfo.bmiHeader.biPlanes = 1;
        bminfo.bmiHeader.biBitCount = 16;
        bminfo.bmiHeader.biCompression = BI_BITFIELDS;
        bminfo.bmiHeader.biSizeImage = 0;//bmih.biWidth * bmih.biHeight * 2;
        bminfo.bmiHeader.biXPelsPerMeter = 0;
        bminfo.bmiHeader.biYPelsPerMeter = 0;
        bminfo.bmiHeader.biClrUsed = 0;
        bminfo.bmiHeader.biClrImportant =0;    bminfo.bmiColors[0].rgbBlue = 0;
        bminfo.bmiColors[0].rgbGreen = 0xF8;
        bminfo.bmiColors[0].rgbRed = 0;
        bminfo.bmiColors[0].rgbReserved = 0;
        bminfo.bmiColors[1].rgbBlue = 0xE0;
        bminfo.bmiColors[1].rgbGreen = 0x07;
        bminfo.bmiColors[1].rgbRed = 0;
        bminfo.bmiColors[1].rgbReserved = 0;
        bminfo.bmiColors[2].rgbBlue = 0x1F;
        bminfo.bmiColors[2].rgbGreen = 0;
        bminfo.bmiColors[2].rgbRed = 0;
        bminfo.bmiColors[2].rgbReserved = 0;    CClientDC dc(this);
        //void *pBits;
        HBITMAP hbitmap = CreateDIBSection(dc.m_hDC,
                                           (const BITMAPINFO *)&bminfo,
                                            DIB_RGB_COLORS,
                                           (VOID **)&pBits,
                                           NULL,
                                           0); memcpy(pBits,Bits,bmih.biWidth * bmih.biHeight * 2);
    free(Bits);
        GdiFlush();
        StretchDIBits(dc.m_hDC,0,0,bminfo.bmiHeader.biWidth,
                      bminfo.bmiHeader.biHeight,0,0,bminfo.bmiHeader.biWidth,
                      bminfo.bmiHeader.biHeight,pBits,(BITMAPINFO *)&bminfo,
                      DIB_RGB_COLORS,SRCCOPY);
        //AfxMessageBox("ok!");
    }
    在View中声明:
    typedef struct {
        BITMAPINFOHEADER bmiHeader;       //位图信息头
        RGBQUAD          bmiColors[3];    //颜色表
        } BMINFO16BIT;//自己包装
    BMINFO16BIT bminfo;
    void *pBits;========================================================
    来试试~~改好点,偶临急临忙乱写的
      

  36.   

    sorry,位数据写入有少少偏移,图象移位了,继续ing >_<.
      

  37.   

    NND,能显示,不过向左偏移了26个像素,汗~~~
    还没找到哪错了.>_<
    水饺先,kakaka
      

  38.   

    呵呵,楼上的很感谢你啊!
        hbitmap = CreateDIBSection(dc.m_hDC,
                                  (const BITMAPINFO *)&bminfo,
                                   DIB_RGB_COLORS,
                                  (VOID **)&pBits,
                                           NULL,
                                           0);
    这个是在干什么啊?我一直比较疑惑BITMAPINFO就是多了一个RGBQUAD,这是干什么用的呢?
    pBits这个是没有初始化的,你放进去干什么呢?我还以为你会用Bits而不是pBits啊!
    函数返回之后pBits是什么啊?
      

  39.   

    然后你又memcpy(pBits,Bits,bmih.biWidth*bmih.biHeight*2);
    这是不是把dib转为ddb呢?
      

  40.   

    今早已能正确显示的了(代码发给土兄了),只不过是Read入数据时出错,不过偶连续回了3帖,所以没法发言 >_<
    上面那是为pBits分配内存,因为hSection句柄设为NULL..然后把数据Copy入pBits,hbitmap并不仅仅包含DDB句柄..你把bminfo适当地修改为你的图片的BITMAPINFOHEADER的数据,然后把你的位数据memcpy()
    到pBits,就能显示的了
      

  41.   

    惑BITMAPINFO就是多了一个RGBQUAD,这是干什么用的呢?这个你可以解释一下吗?我觉得这个RGBQUAD简直就像是多余的!
      

  42.   

    你都知道这个是掩码了,当:bminfo.bmiHeader.biCompression = BI_BITFIELDS时,原来的色彩表被3个DWORD所占据....
    如果不设置这3个掩码,将得不到正确的色彩..
    你试去掉这:
    typedef struct {
        BITMAPINFOHEADER bmiHeader;       //位图信息头
        //RGBQUAD          bmiColors[3];  //3个DD
        } BMINFO16BIT;//自己包装
    和注释掉色彩表的附值实验一下就知道了..
      

  43.   

    看看这个:http://www.fantasiasoft.net/Documents/BMPFormat.htm
    有位图的详细介绍,包括16Bit.
      

  44.   

    hbitmap = CreateDIBSection(dc.m_hDC,
                                  (const BITMAPINFO *)&bminfo,
                                   DIB_RGB_COLORS,
                                  (VOID **)&pBits,
                                           NULL,
                                           0);解释清楚点:上面那个是根据bminfo创建了一张空白可写入数据的位图,然后就把数据倒向pBits,土星兄这次应该明了吧..该水饺了...
    ZZZZZzzzzzzzzz.
      

  45.   

    BOOL CScreenView1::LoadBMP(HGLOBAL *phBuf, HGLOBAL *phDIB, CPalette *pPal)
    {
    if(*phDIB)
    {
    GlobalFree(*phDIB);
    *phDIB = NULL;
    }
    if(*phBuf == NULL)
    {
    return FALSE;
    } long nFileLen;
    nFileLen = GlobalSize(*phBuf); HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen);
    if(hDIB == NULL)
    return FALSE; memcpy((LPSTR)hDIB, *phBuf, nFileLen - sizeof(BITMAPFILEHEADER)); BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB; int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
                        1 << bmInfo.bmiHeader.biBitCount;
    if(nColors <= 256)
    {
    //如果小于256色,就建立调色板
    UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
    LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300;
    pLP->palNumEntries = nColors; for(int i = 0; i < nColors; i++)
    {
    pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
    pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
    pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
    pLP->palPalEntry[i].peFlags = 0;
    } pPal->CreatePalette(pLP);
    delete[] pLP;
    }
    *phDIB = hDIB;
    return TRUE;
    }
      

  46.   

    void CScreenView1::DrawDib(CDC *pDC, HGLOBAL hDib, CPalette *pPal)
    {
    //位图指针
    LPVOID lpDibBits;
    BOOL   bSuccess = FALSE; //取得位图说明
    BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDib;
    //判断颜色表是否不足
    int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
                   1 << bmInfo.bmiHeader.biBitCount; //得到色彩数
    if(bmInfo.bmiHeader.biBitCount > 8) //如果是256色以上
    {
    lpDibBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + 
    bmInfo.bmiHeader.biClrUsed) + 
    ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
    }
    else
    {
    lpDibBits = (LPVOID)(bmInfo.bmiColors + nColors);
    }
    //取得指向位图的数据指针
    if(pPal && (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE))
    {
    pDC->SelectPalette(pPal, FALSE);
    pDC->RealizePalette();
    }
    if(m_ShowMode == 2)              //完整显示
    {
    ::SetDIBitsToDevice(pDC->m_hDC,          //hDC
               0,                        //DestX
       0,                        //DestY
       bmInfo.bmiHeader.biWidth, //nDestWidth
       bmInfo.bmiHeader.biHeight,//nDestHeight
       0,                        //SrcX
       0,                        //SrcY
       0,                        //nStartScan
       bmInfo.bmiHeader.biHeight,//nNumScans
       lpDibBits,                //lpBits
       (LPBITMAPINFO)hDib,       //lpBitsInfo
       DIB_RGB_COLORS);          //wUsage 
    }
    else
    {
    CRect rect;
    GetClientRect(&rect);
    int height;//按原来的比例显示图像,这里没有考虑窗口被调整成扁平的情况
    if(m_ShowMode == 0)
    height = rect.Width()*bmInfo.bmiHeader.biHeight/bmInfo.bmiHeader.biWidth;
    else if(m_ShowMode == 1)
    height = rect.Height();
    else 
    return;
    ::StretchDIBits(pDC->m_hDC,
    0, (rect.Height() - height)/2, rect.Width(), height,
    0, 0, bmInfo.bmiHeader.biWidth, bmInfo.bmiHeader.biHeight,
    lpDibBits,
    (LPBITMAPINFO)hDib,
    DIB_RGB_COLORS, 
    SRCCOPY);
    }
    }
      

  47.   

    lambochan(打杂)
    怎么你就知道水饺啊:)
    http://www.fantasiasoft.net/Documents/BMPFormat.htm
    这个文章我原来看过了,刚开始分析的时候就看的这个
    主要是我觉得BITMAPINFO这个结构中的RGBQUAD[1]从你的程序看来是什么值无所谓啊,是不是这样的,具体怎么来使用RGBQUAD会根据bminfo.bmiHeader.biCompression的值来读取BITMAPINFOHEADER后面的值,是吗?
      

  48.   

    l_b_q() 可以说说你的函数的参数表吗?
      

  49.   

    BOOL CScreenView1::LoadBMP(HGLOBAL *phBuf, HGLOBAL *phDIB, CPalette *pPal)
    phBuf,原始的位图数据,开始是BITMAPINFO结构
    phDIB,从phBuf中提取要显示的位图数据,就是下面函数的hDib
    pPal, 建立的调色板
      

  50.   

    谢谢楼上的,
    lambochan(打杂),我也想知道如下的问题:
    主要是我觉得BITMAPINFO这个结构中的RGBQUAD[1]从你的程序看来是什么值无所谓啊,是不是这样的,具体怎么来使用RGBQUAD会根据bminfo.bmiHeader.biCompression的值来读取BITMAPINFOHEADER后面的值,是吗?
    看大家这么帮我,我再给帖子加50分:)
      

  51.   

    SURE..
    其实biBitCount<=8时,才有调色板(色彩表)的,不过正如那篇BMP资料说的那样,16位色是最麻烦的,当bminfo.bmiHeader.biCompression =BI_RGB时,不需要设置调色板,像素值直接按(WORD)0bbbbbgggggrrrrr储存(15位32K色),当为
    bminfo.bmiHeader.biCompression = BI_BITFIELDS时,色彩表位置被那3个DD占据,它并不是调色板,而是像素值的掩码,所以必须设置那3个bmiColors,不设置的话得不到正确的颜色..
    具体我也是实验过才知道的,呵呵..
      

  52.   

    我原来就做过你说的实验了,确实显示出来就是乱的,
    这么说来BITMAPINFO这个结构中的RGBQUAD[1]完全是多余的,随便填写什么值都可以了!
      

  53.   

    我真的想不出BITMAPINFO这个结构中的RGBQUAD[1]在什么时候会有用,好象完全没有意义嘛!
      

  54.   

    不是吧..有用且必须的
    你可以去掉这3个DD,但颜色不正确。
    你还可以试试把全它设成0,程序会崩溃。kaka.
      

  55.   

    RGBQUAD当然有用啦,它是其后位数据的颜色索引来的哦(biBitCount<=8).16Bit是古怪(并不是色彩表,是掩码),24Bit没有.
      

  56.   

    我知道RGBQUAD是调色板,但是RGBQUAD[1]只有一个数组,这看来无论在哪种情况下作为调色板都是不正确的啊!
      

  57.   

    哎...
    RGBQUAD[1]不是表示只有1个数组,而是表示色彩表中只有1种颜色呀,如256色(8Bit,biBitCount = 8)时:RGBQUAD bmiColors[256] <===变成这样了,有256种色彩.
    RGBQUAD其实就是调色板位图位数据的颜色索引,当根据这个色彩表实现了Palette,位图才能显示正确的颜色..调色板位图只有一个RGBQUAD数组,而biBitCount决定了这个色彩表的数组大小,并非是说:RGBQUAD bmiColors[2] == 两个调色板,这只是说这个色彩表里有两种颜色.
    也就是告诉你实现Palette时,颜色只有两种..
    通常,biBitCount>8时,没有色彩表的,但16Bit例外,16Bit位图的bminfo.bmiHeader.biCompression = BI_BITFIELDS时,色彩表为:RGBQUAD bmiColors[3],这并非是说有3个调色板,而是色彩表数组大小为3,本来色彩表储存着位图位数据的颜色值,但16Bit却不是,这3个DD只是位数据的颜色值的掩码,所以根本不需要实现Palette..不知你看明了没有,偶写得乱糟糟的,再写下去,可能把自己也弄糊涂了,呵呵~~
      

  58.   

    补充一句:RGBQUAD并不是调色板,只是色彩表,Palette是根据这个色彩表大小来实现位图颜色选入的,不要混熬了..
      

  59.   

    忘了说:
        RGBQUAD不是什么值都无所谓的,它保存着"调色板位图"里位数据的颜色值,而位数据只是色彩表里所保存颜色的索引号.
    OK~~又三帖了,汗ing
      

  60.   

    呵呵,你混mop的吧?看你的文章真是很困难啊:)
    我确实混淆了调色板和色彩表,你这一说,我结合那个文章一看就清楚些了。
    是不是在bitmapinfo中虽然定义的RGBQUAD bmiColors[1]但RGBQUAD结构到底有多少了数组,还是由BITMAPINFOHEADER中的相关项来决定长度的?
    其实可以说RGBQUAD bmiColors[1]相当于一个占位的作用!
      

  61.   

    HBITMAP hbp;
    hbp = CreateDIBitmap(h_DC, 
                    (BITMAPINFOHEADER *)binfo, 
                    CBM_INIT, 
                    (LPSTR)pDate, 
                    (LPBITMAPINFO)binfo, 
                    DIB_RGB_COLORS );
    //或許有幫助???
      

  62.   

    zhangcrony(前后都是路,橫豎都是一) 谢谢!
    lambochan(打杂)最后来一次嘛,
    ---------------------------------------------------------------------------
    我确实混淆了调色板和色彩表,你这一说,我结合那个文章一看就清楚些了。
    是不是在bitmapinfo中虽然定义的RGBQUAD bmiColors[1]但RGBQUAD结构到底有多少了数组,还是由BITMAPINFOHEADER中的相关项来决定长度的?
    其实可以说RGBQUAD bmiColors[1]相当于一个占位的作用!
    ----------------------------------------------------------------
    是不是占位的作用嘛,水饺水饺:)
      

  63.   

    那个DD是被BITMAPINFOHEADER里的biBitCount、biCompression和biClrUsed所左右的.
    水饺去了~~
      

  64.   

    上百帖啊?kaka ^_^
    有用的,不是占位..
    你可以做个实验:举个256色图片位例:
    typedef struct {
        BITMAPINFOHEADER bmiHeader;       //位图信息头
        RGBQUAD          bmiColors[256];  //现在256色了
        } BMINFO256;//封装为256色.
    BMINFO256 256bitmap;
    用这个Load入BITMAPINFOHEADER和RGBQUAD.
    当用CreatDIBSection()(用上面的(const BITMAPINFO *)&256bitmap)创建一幅8Bit的空白DIB,然后倒入位数据,实现Palette,把图象显示出来..
    现在可以来试试了:
    这个256bitmap.bmiColors读入了刚显示位图的色彩表,现在要它变换:
    for(int i=0;i<16;++i)
    {
        256bitmap.bmiColors[i].rgbBlue = 256bitmap.bmiColors[i+16].rgbBlue;
        256bitmap.bmiColors[i].rgbGreen = 256bitmap.bmiColors[i+16].rgbGreen;
        256bitmap.bmiColors[i].rgbRed = 256bitmap.bmiColors[i+16].rgbRed;
        256bitmap.bmiColors[i].rgbReserved = 256bitmap.bmiColors[i+16].rgbReserved;
    }//把色彩表的前16种颜色改为和后面16种相同的颜色;
    接着:
    Invalidate();
    UpdateWindow();//重新显示..注意,并没重新实现调色板..
    现在,你可以看到图片变得古怪了..呵呵,因为色彩表的前16项颜色被改变了.可见,并不是在占位哟..
      

  65.   

    呵呵,我的帖子还置顶了:) lambochan(打杂) ,这个帖子抄热了也是你的功劳啊!
    我想我基本明白了,这个RGBQUAD bmiColors[1]官方定义的是1长度的数组,但是因为数据实际上是连续储存的,究竟如何解释后面这些连续的数据,哪些是色彩表,哪些是有效数据还是由前面的BITMAPINFOHEADER来决定的。
    因为色彩表长度的不固定,所以使我迷惑了。
    楼上的,我说的对吧?
      

  66.   

    就是这样了.
    由BITMAPINFOHEADER的几个值域来决定的..置顶了吗?偶没留意啊,keke
      

  67.   

    说了半天原来我是想知道的是这个
    我想我基本明白了,这个RGBQUAD bmiColors[1]官方定义的是1长度的数组,但是因为数据实际上是连续储存的,究竟如何解释后面这些连续的数据,哪些是色彩表,哪些是有效数据还是由前面的BITMAPINFOHEADER来决定的。
      

  68.   

    我的代码如下:HBITMAP frontbit;
    HDC tmphdc;
    BITMAPINFO bitmapinfo;
    void *bmpdata;
    frontbit=CreateDIBSection(tmphdc,&bitmapinfo,DIB_RGB_COLORS,(VOID**)&bmpdata,NULL,0);为什么CreateDIBSection后bmpdata为NULL?
      

  69.   

    你的bitmapinfo读入DD了?或付值了?
      

  70.   

    问题解决了,是我将其格式设成了YUY2。谢谢
      

  71.   

    我选择了列表框的WS_HSCROLL,LBS_EXTENDED,WS_VSCROLL风格,可不知道为什么列表项的文字
    超出右界时,并不出现水平滚动条?
      

  72.   

    lambochan(打杂) 把代码发给我也来看下