如何创建bitmap

zyrr159487 2010-08-20 03:31:10
用了两种方法创建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的错误在哪里,另外肯定有其他方法绘制位图,希望大家不吝赐教
...全文
1185 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
zyrr159487 2010-08-27
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 zydzmapx 的回复:]
过了这多天还没人解决,帮楼主顶一下增加眼球
[/Quote]
...已经结贴了
zydzmapx 2010-08-27
  • 打赏
  • 举报
回复
过了这多天还没人解决,帮楼主顶一下增加眼球
疯癫小程序 2010-08-25
  • 打赏
  • 举报
回复
最近比较忙,帮顶!
hotwaltz 2010-08-25
  • 打赏
  • 举报
回复
原来如此
NIKE霸天虎 2010-08-25
  • 打赏
  • 举报
回复
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
这里的bmiColors就是调色板。
多看MSDN
mhm0902 2010-08-25
  • 打赏
  • 举报
回复
人民邮电出的 数字图像处理 挺好
鸟人 冈沙雷斯 的 数字图像处理
zyrr159487 2010-08-23
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 hastings 的回复:]
http://blog.chinaunix.net/u2/69227/showart_2000436.html
你把链接里的看完就行了~~里面有四种位图格式。
另外,你对biClrUsed字段的意思理解是错误的。
当位图是8位以下时,有颜色表。
若biClrUsed为0,则颜色表的RGBQUAD个数为2<<biBitCount个;
若biClrUsed不为0(小于2<<biBitCoun……
[/Quote]
GOOD
hastings 2010-08-22
  • 打赏
  • 举报
回复
http://blog.chinaunix.net/u2/69227/showart_2000436.html
你把链接里的看完就行了~~里面有四种位图格式。
另外,你对biClrUsed字段的意思理解是错误的。
当位图是8位以下时,有颜色表。
若biClrUsed为0,则颜色表的RGBQUAD个数为2<<biBitCount个;
若biClrUsed不为0(小于2<<biBitCount),则颜色表的RGBQUAD个数为biClrUsed个;
你这里的biClrUsed应该赋值为2.
具体细节看链接。
xxd_qd 2010-08-21
  • 打赏
  • 举报
回复
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]分别设成什么颜色了。
zyrr159487 2010-08-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cnzdgs 的回复:]
单色位图是只有两种颜色的位图,这两种颜色不一定是黑和白,由位图信息中的调色板数据决定。你没有给出调色板数据,所以颜色是未知的。
[/Quote]
原来如此,难怪release下每次随即出现两种颜色
zyrr159487 2010-08-21
  • 打赏
  • 举报
回复
这个问题解决了,顺便问下有没有知道有比较详细的bimap的书籍或者文献,待会结贴
zyrr159487 2010-08-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xxd_qd 的回复:]
带调色板的BITMAPINFO(8位以下)必须动态分配空间,因为就算黑白位图也至少有两个调色板入口。你没有动态分配,因此在访问调色板第二个入口的时候实际上已经指针越界。
“有人说是内存问题,有人说是颜色没设置好”——你的方法1里我甚至根本没看见你给调色板赋值,因此确切地说,两种错误全有。
[/Quote]
果然是两种问题都有,先解决颜色问题

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); //选入位图
wing_0706 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cnzdgs 的回复:]
单色位图是只有两种颜色的位图,这两种颜色不一定是黑和白,由位图信息中的调色板数据决定。你没有给出调色板数据,所以颜色是未知的。
[/Quote]
支持啊。。。
cnzdgs 2010-08-20
  • 打赏
  • 举报
回复
单色位图是只有两种颜色的位图,这两种颜色不一定是黑和白,由位图信息中的调色板数据决定。你没有给出调色板数据,所以颜色是未知的。
zyrr159487 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xiaoyilong19 的回复:]
方法1是不是什么变量没有初始化设置,导致两个版本不同,可能真是调色板的问题,仔细改正下看看
[/Quote]
恩,我再去看看bitmap的结构
zyrr159487 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xxd_qd 的回复:]
带调色板的BITMAPINFO(8位以下)必须动态分配空间,因为就算黑白位图也至少有两个调色板入口。你没有动态分配,因此在访问调色板第二个入口的时候实际上已经指针越界。
“有人说是内存问题,有人说是颜色没设置好”——你的方法1里我甚至根本没看见你给调色板赋值,因此确切地说,两种错误全有。
[/Quote]
大哥,怎么又是你。。。囧了
zyrr159487 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xxd_qd 的回复:]
带调色板的BITMAPINFO(8位以下)必须动态分配空间,因为就算黑白位图也至少有两个调色板入口。你没有动态分配,因此在访问调色板第二个入口的时候实际上已经指针越界。
“有人说是内存问题,有人说是颜色没设置好”——你的方法1里我甚至根本没看见你给调色板赋值,因此确切地说,两种错误全有。
[/Quote]
额,这个调色板的第二个入口指的是哪个,要如何动态分配空间呢,有代码最好了, 谢谢
xiaoyilong19 2010-08-20
  • 打赏
  • 举报
回复
方法1是不是什么变量没有初始化设置,导致两个版本不同,可能真是调色板的问题,仔细改正下看看
hastings 2010-08-20
  • 打赏
  • 举报
回复
哎…不知道LZ哪里拷来的代码…越界得一塌糊涂…
yyds2022 2010-08-20
  • 打赏
  • 举报
回复
歌没看bmp结构很久了
加载更多回复(2)

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧