用了两种方法创建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 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里我甚至根本没看见你给调色板赋值,因此确切地说,两种错误全有。
是调色板的问题 还是图像数据的问题?
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]分别设成什么颜色了。
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); //选入位图
你把链接里的看完就行了~~里面有四种位图格式。
另外,你对biClrUsed字段的意思理解是错误的。
当位图是8位以下时,有颜色表。
若biClrUsed为0,则颜色表的RGBQUAD个数为2<<biBitCount个;
若biClrUsed不为0(小于2<<biBitCount),则颜色表的RGBQUAD个数为biClrUsed个;
你这里的biClrUsed应该赋值为2.
具体细节看链接。
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
这里的bmiColors就是调色板。
多看MSDN