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

王楚铁 2011-02-22 06:51: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居然有蓝色的底色。。。。不解。。

求高人~~~~~
...全文
176 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
fishion 2011-02-23
  • 打赏
  • 举报
回复
我不是给你说了吗,参考上个帖子
王楚铁 2011-02-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 tandyt 的回复:]

你要保存为8位的灰度图像还是8位的彩色图像啊?如果是8位的图像,存储到文件时,要在所有像素数据前加上颜色索引表。

比如:一个8位的bmp文件,包含如下结构:

位图文件头、文图信息头、颜色索引表、像素数据。如果是24位或者32位的位图,就没有“颜色索引表”这段数据。
[/Quote]我是新手,请讲通俗一些,具体还要修改何处的代码????谢谢……
手机写程序 2011-02-23
  • 打赏
  • 举报
回复
CImage::Save(...)比较简单。
TandyT 2011-02-22
  • 打赏
  • 举报
回复
你要保存为8位的灰度图像还是8位的彩色图像啊?如果是8位的图像,存储到文件时,要在所有像素数据前加上颜色索引表。

比如:一个8位的bmp文件,包含如下结构:

位图文件头、文图信息头、颜色索引表、像素数据。如果是24位或者32位的位图,就没有“颜色索引表”这段数据。

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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