求助一个关于存储bmp位图的问题。。。。

tht228 2011-02-22 06:50:56
我就用了一个函数。放了一个按钮调用一次。代码如下:
[code=C]/C++
void CMyTestDlg::CopyScreenToFile(CWnd *pWnd, CRect *lpRect, LPCTSTR Dstfile)
{
if(!IsWindow(pWnd->GetSafeHwnd()))
{
AfxMessageBox("窗口句柄无效");
return ;
}
CDC *pDC = pWnd->GetDC();
int Width = lpRect->Width();
int Height = lpRect->Height();

CDC memDC;//内存DC
memDC.CreateCompatibleDC(pDC);
CBitmap memBitmap;//建立和屏幕兼容的bitmap
memBitmap.CreateCompatibleBitmap(pDC, Width, Height);
memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC
memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC

//以下代码保存memDC中的位图到文件
BITMAP bmp;
memBitmap.GetBitmap(&bmp);//获得位图信息

DWORD bmpBytesSize = bmp.bmWidthBytes * bmp.bmHeight;

BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bmpBytesSize ;//文件总的大小
bfh.bfType = (WORD)0x4d42;

BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小 !!!!问题在这里
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmpBytesSize;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度

BYTE * p = new byte[bmpBytesSize];//申请内存保存位图数据
GetDIBits(memDC.m_hDC,
(HBITMAP) memBitmap.m_hObject, 0, Height,
p,(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据

for(DWORD i=0;i<bmpBytesSize-4;i)
{
BYTE tmp_uchar = p[i];
p[i] = p[i+1];
p[i+1] = p[i+2];
p[i+2] = p[i+3];
p[i+3] = tmp_uchar;
i += 4;
}
try
{
CFile fp(Dstfile,CFile::modeCreate | CFile::modeWrite);
fp.Write(&bfh, sizeof(BITMAPFILEHEADER));//写入位图文件头
fp.Write(&bih, sizeof(BITMAPINFOHEADER));//写入位图信息头
fp.Write(p, bmp.bmWidthBytes * bmp.bmHeight);//写入位图数据
fp.Close();
}
catch( CFileException * e )
{
e->Delete();
}
delete []p;
}[/code]
以上是函数。调用的时候也很简单,一个按钮一点就行,代码如下:
[code=C]/C++
void CMyTestDlg::OnButton1()
{
CRect rcRect;
rcRect.top = 0;
rcRect.bottom = 200;
rcRect.left = 0;
rcRect.right = 400;
CopyScreenToFile(this,&rcRect,"C:\\123.bmp");
}[/code]

我的问题是,BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;// 这一句话中,我调试了一下,该值为32,也就是32位的。可是我现在只能要存8位的BMP才能进行下一步工作。我将这个值改为8的话,后面在创建文件的时候程序就崩了。

CFile fp(Dstfile,CFile::modeCreate | CFile::modeWrite); //这句的时候就崩掉~


是不是单单将这个值改为8是不行的?还需要其他设置??

另外感兴趣的朋友可以建一个对话框,试试我的代码,存储出来的BMP居然有蓝色的底色。。。。不解。。

求高人~~~~~
...全文
71 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
hastings 2011-02-23
  • 打赏
  • 举报
回复
去掉这些试试:
for(DWORD i=0;i <bmpBytesSize-4;i)
{
BYTE tmp_uchar = p[i];
p[i] = p[i+1];
p[i+1] = p[i+2];
p[i+2] = p[i+3];
p[i+3] = tmp_uchar;
i += 4;
}
fishion 2011-02-23
  • 打赏
  • 举报
回复
改成8位后,文件的结构应该也变了吧,你可能要了解下32位位图变8位位图要修改哪些地方了
tht228 2011-02-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 fishion 的回复:]

BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小 !!!!问题在这里
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes ……
[/Quote]我试过你的方法了,写文件不会崩了,但是截取图像的坐标和图像的大小跟我所规定的不相符啊。我在按钮里规定的是400x200的,可是改成8位后,截图的坐标发生了很大的偏移…………不信你可以建一个对话框的小工程把我的代码拷进去试试。别忘了在对话框上多放些控件,方便观察截图位置。
fishion 2011-02-22
  • 打赏
  • 举报
回复
BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小 !!!!问题在这里
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmpBytesSize;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度

BYTE * p = new byte[bmpBytesSize];//申请内存保存位图数据
GetDIBits(memDC.m_hDC,
(HBITMAP) memBitmap.m_hObject, 0, Height,
p,(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据

for(DWORD i=0;i <bmpBytesSize-4;i)
{
BYTE tmp_uchar = p[i];
p[i] = p[i+1];
p[i+1] = p[i+2];
p[i+2] = p[i+3];
p[i+3] = tmp_uchar;
i += 4;
}
try
{
bih.biBitCount = 8; CFile fp(Dstfile,CFile::modeCreate | CFile::modeWrite);
fp.Write(&bfh, sizeof(BITMAPFILEHEADER));//写入位图文件头
fp.Write(&bih, sizeof(BITMAPINFOHEADER));//写入位图信息头
fp.Write(p, bmp.bmWidthBytes * bmp.bmHeight);//写入位图数据
fp.Close();
}
catch( CFileException * e )
{
e->Delete();
}
delete []p;
fishion 2011-02-22
  • 打赏
  • 举报
回复
GetDIBits(memDC.m_hDC,
(HBITMAP) memBitmap.m_hObject, 0, Height,
p,(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据

应该是这里出问题了,你上面修改了bih为8,这里又使用了bih
tht228 2011-02-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fishion 的回复:]
你就是写入操作而且,你怎么写,数据写错了最多就是不能显示图片而已,不会导致崩溃的,应该是其它地方出问题了
[/Quote]

确实是将32改为8后才出现的问题。。
我调试了一下,就是创建文件的那一句话崩溃掉了。是不是溢出了~
如果改成16的话,图像也能存储,显示起来则有点发虚
fishion 2011-02-22
  • 打赏
  • 举报
回复
你就是写入操作而且,你怎么写,数据写错了最多就是不能显示图片而已,不会导致崩溃的,应该是其它地方出问题了

19,469

社区成员

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

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