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

王楚铁 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居然有蓝色的底色。。。。不解。。

求高人~~~~~
...全文
119 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位位图要修改哪些地方了
王楚铁 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
王楚铁 2011-02-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fishion 的回复:]
你就是写入操作而且,你怎么写,数据写错了最多就是不能显示图片而已,不会导致崩溃的,应该是其它地方出问题了
[/Quote]

确实是将32改为8后才出现的问题。。
我调试了一下,就是创建文件的那一句话崩溃掉了。是不是溢出了~
如果改成16的话,图像也能存储,显示起来则有点发虚
fishion 2011-02-22
  • 打赏
  • 举报
回复
你就是写入操作而且,你怎么写,数据写错了最多就是不能显示图片而已,不会导致崩溃的,应该是其它地方出问题了
内容概要:本文围绕可变桨叶四旋翼无人机的规范控制与点对点运动模拟展开,重点研究优化推力分配策略在翻转动作中的应用与性能比较。通过Matlab代码实现,构建了四旋翼动力学模型,并设计了多种控制算法以实现精确的姿态调整与轨迹跟踪。研究对比了不同推力分配方案在执行高机动性翻转动作时的稳定性、能耗效率与响应速度,旨在提升无人机在复杂飞行任务中的动态性能与控制精度。该仿真研究为无人机飞控系统的设计与优化提供了理论依据和技术支持。; 适合人群:具备一定自动控制理论基础和Matlab编程能力,从事无人机控制、飞行器动力学或机器人系统研究的科研人员及研究生。; 使用场景及目标:① 实现四旋翼无人机在三维空间中的精确点对点运动控制;② 对比分析不同推力分配策略在执行翻转等高难度动作时的控制效果与能耗表现,优化飞行性能;③ 为无人机自主飞行、特技飞行及复杂环境下的机动控制提供算法验证平台。; 阅读建议:此资源以Matlab仿真为核心,建议读者结合相关控制理论知识,深入理解代码实现细节,重点关注动力学建模、控制律设计与推力分配模块。在学习过程中,应动手调试参数,复现文中翻转动作的仿真结果,并尝试拓展至其他复杂飞行任务,以加深对无人机控制机理的理解。

19,465

社区成员

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

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