用了两种方法创建bitmap
方法1
 
  BITMAPINFO bmpInfo;  //创建位图        
    bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = (int)m_Rect.width();//宽度
    bmpInfo.bmiHeader.biHeight = (int)m_Rect.height();//高度
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 1;
    bmpInfo.bmiHeader.biCompression = BI_RGB;
    bmpInfo.bmiHeader.biSizeImage = 0;
    bmpInfo.bmiHeader.biXPelsPerMeter = 0;
    bmpInfo.bmiHeader.biYPelsPerMeter = 0;
    bmpInfo.bmiHeader.biClrImportant = 0;
    bmpInfo.bmiHeader.biClrUsed = 1;//颜色表中使用的颜色数
    void* pArray = NULL;
    HBITMAP hbmp = CreateDIBSection(NULL, &bmpInfo, DIB_RGB_COLORS, &pArray, NULL, 0);//创建DIB
    ASSERT(hbmp != NULL);
    UINT uiTotalBytes = (((int)m_Rect.width() + 31) / 32) * 4 * (int)m_Rect.height();
    memset(pArray, 255, uiTotalBytes);
    m_pMemBmp->Attach(hbmp);
    m_pMemDc->CreateCompatibleDC(NULL);//创建空的CDC  
    m_pMemDc->SelectObject(m_pMemBmp); //选入位图方法1贴图能成功,能贴60000*60000左右的单色位图,在debug下运行良好,但是在release下居然会贴出带颜色的位图,这点我百思不得其解,有人说是内存问题,有人说是颜色没设置好。方法2
    ///////////////////////////////////创建位图/////////////////////////////    HBITMAP hbmp = CreateBitmap((int)m_Rect.width(), (int)m_Rect.height(), 1, 1, NULL);
    m_pMemBmp->Attach(hbmp);
    ASSERT(m_pMemBmp != NULL);
    BYTE array[X_GRAPH_POINT * Y_GRAPH_POINT];
    memset(array, 0, X_GRAPH_POINT * Y_GRAPH_POINT);
    m_pMemBmp->SetBitmapBits(X_GRAPH_POINT * Y_GRAPH_POINT, array);
    m_pMemDc->CreateCompatibleDC(NULL);            //创建空的DC  
    m_pMemDc->SelectObject(m_pMemBmp); //选入位图
在方法1贴出带颜色的位图后,又不得不换了种方式绘图,结果在release下能够绘出正常的单色位图(只有黑白),不过它只能贴20000*20000左右的位图。
所以我想询问下方法1的错误在哪里,另外肯定有其他方法绘制位图,希望大家不吝赐教

解决方案 »

  1.   

    带调色板的BITMAPINFO(8位以下)必须动态分配空间,因为就算黑白位图也至少有两个调色板入口。你没有动态分配,因此在访问调色板第二个入口的时候实际上已经指针越界。
    “有人说是内存问题,有人说是颜色没设置好”——你的方法1里我甚至根本没看见你给调色板赋值,因此确切地说,两种错误全有。
      

  2.   

    不会这么悬疑吧。release版本带的是啥颜色呢?
    是调色板的问题 还是图像数据的问题?
      

  3.   

    typedef struct tagBITMAPINFO { 
      BITMAPINFOHEADER bmiHeader; 
      RGBQUAD          bmiColors[1]; 
    } BITMAPINFO, *PBITMAPINFO; 
    这里的bmiColors就是调色板。对于不同位数的位图,调色板的入口数是不同的,8位以下是(2^位数)个入口,24位没有调色板,16位和32位根据不同情况可能没有或者有3个。因此,在定义结构的时候没有办法明确指定bmiColors这个数组的大小。既然没办法事先确定数组大小,看起来这里似乎不应该用数组,而是应该用个RGBQUAD的指针更合理些,但实际上,如果用指针的话,那就需要另开辟一块内存来存放调色板,而且更重要的是:这块内存跟BITMAPINFO本身所占用的内存不见得连在一起。这会带来不少的麻烦。为了保证调色板所占的内存与BITMAPINFO的内存完全连在一起,微软用了点小技巧,就是用一个数组而不是指针来定义这个bmiColors。此时数组大小并不是我们所关心的问题(因为它是无法事先确定的),所以用个1就行,这样就可以保证bmiColors的存储空间会紧跟在bmiHeader之后。正因为这个bmiColors数组的大小是随便写的,因此,除非是没有调色板数据的位图,否则在使用BITMAPINFO的时候,是不可能直接定义变量的(那样你将没地方存调色板数据),而只能动态分配:BITMAPINFO *pbmi = (BITMAPINFO *)(new BYTE [sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 调色板入口数]);
    对于8位以下的位图,位图数据实际上是调色板的索引。例如对于1位位图,一共只有0和1两个取值,至于0和1分别是什么颜色,那看你把bmiColors[0]和bmiColors[1]分别设成什么颜色了。
      

  4.   

    原来如此,难怪release下每次随即出现两种颜色
      

  5.   

    果然是两种问题都有,先解决颜色问题    BITMAPINFO bmpInfo;  //创建位图        
        bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmpInfo.bmiHeader.biWidth = (int)m_Rect.width();
        bmpInfo.bmiHeader.biHeight = (int)m_Rect.height();
        bmpInfo.bmiHeader.biPlanes = 1;
        bmpInfo.bmiHeader.biBitCount = 1;
        bmpInfo.bmiHeader.biCompression = BI_RGB;
        bmpInfo.bmiHeader.biSizeImage = 0;
        bmpInfo.bmiHeader.biXPelsPerMeter = 0;
        bmpInfo.bmiHeader.biYPelsPerMeter = 0;
        bmpInfo.bmiHeader.biClrImportant = 0;
        bmpInfo.bmiHeader.biClrUsed = 1;//颜色表中使用的颜色数    bmpInfo.bmiColors[0].rgbRed   = 255; //设置颜色
        bmpInfo.bmiColors[0].rgbGreen = 255;
        bmpInfo.bmiColors[0].rgbBlue  = 255;
        bmpInfo.bmiColors[0].rgbReserved = 0;
        bmpInfo.bmiColors[1].rgbRed   = 0;
        bmpInfo.bmiColors[1].rgbGreen = 0;
        bmpInfo.bmiColors[1].rgbBlue  = 0;
        bmpInfo.bmiColors[1].rgbReserved = 0;这样设置后颜色果然没问题,但是debug下会提示我bmpInfo这个corrupt
    接下来按楼上说的动态分配内存来解决内存问题
    BITMAPINFO *pbmi = (BITMAPINFO *)(new BYTE [sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2]);
        pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pbmi->bmiHeader.biWidth = (int)m_Rect.width();
        pbmi->bmiHeader.biHeight = (int)m_Rect.height();
        pbmi->bmiHeader.biPlanes = 1;
        pbmi->bmiHeader.biBitCount = 1;
        pbmi->bmiHeader.biCompression = BI_RGB;
        pbmi->bmiHeader.biSizeImage = 0;
        pbmi->bmiHeader.biXPelsPerMeter = 0;
        pbmi->bmiHeader.biYPelsPerMeter = 0;
        pbmi->bmiHeader.biClrImportant = 0;
        pbmi->bmiHeader.biClrUsed = 1;//颜色表中使用的颜色数    pbmi->bmiColors[1].rgbRed   = 0;//设置颜色
        pbmi->bmiColors[1].rgbGreen = 0;
        pbmi->bmiColors[1].rgbBlue  = 0;
        pbmi->bmiColors[1].rgbReserved = 0;
        pbmi->bmiColors[0].rgbRed   = 255;
        pbmi->bmiColors[0].rgbGreen = 255;
        pbmi->bmiColors[0].rgbBlue  = 255;
        pbmi->bmiColors[0].rgbReserved = 0;
        void* pArray = NULL;
        HBITMAP hbmp = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pArray, NULL, 0);
        ASSERT(hbmp != NULL);
        UINT uiTotalBytes = (((int)m_Rect.width() + 31) / 32) * 4 * (int)m_Rect.height();
        memset(pArray, 255, uiTotalBytes);
        m_pMemBmp->Attach(hbmp);
        m_pMemDc->CreateCompatibleDC(NULL);//创建空的CDC  
        m_pMemDc->SelectObject(m_pMemBmp); //选入位图
      

  6.   

    这个问题解决了,顺便问下有没有知道有比较详细的bimap的书籍或者文献,待会结贴
      

  7.   

    http://blog.chinaunix.net/u2/69227/showart_2000436.html
    你把链接里的看完就行了~~里面有四种位图格式。
    另外,你对biClrUsed字段的意思理解是错误的。
    当位图是8位以下时,有颜色表。
    若biClrUsed为0,则颜色表的RGBQUAD个数为2<<biBitCount个;
    若biClrUsed不为0(小于2<<biBitCount),则颜色表的RGBQUAD个数为biClrUsed个;
    你这里的biClrUsed应该赋值为2.
    具体细节看链接。
      

  8.   

    typedef struct tagBITMAPINFO {  
      BITMAPINFOHEADER bmiHeader;  
      RGBQUAD bmiColors[1];  
    } BITMAPINFO, *PBITMAPINFO;  
    这里的bmiColors就是调色板。
    多看MSDN