使用MFC绘图,200×200的位图每秒只能画两次,如何提高速度?

zyb083 2014-12-03 08:30:36
大家好!刚开始学习用MFC写一个界面,需要用伪彩色图动态的显示一个200×200的矩阵。现在实现了基本功能,但图像的刷新速度有些慢,在一秒两帧左右。
使用播放器播放视频时不是可以到每秒十几帧么,为何动态绘图的速度这么慢。
我使用的方法是先在内存定义一个位图对象,完成位图对象的绘图后通过BitBlt()显示到界面上。
下面给出相关的代码,不知道有什么提高速度的办法?
谢谢大家!
CBitmap pBmp_MainshowP1;                                              // 位图类
CBitmap pBmp_Sub1,pBmp_Sub2,pBmp_Sub3;


MemDC_ShowMain.CreateCompatibleDC(pDC_MainshowP1); //pDC_MainshowP1 NULL
pBmp_MainshowP1.CreateCompatibleBitmap(pDC_MainshowP1,pRect_MainshowP1.Width(),pRect_MainshowP1.Height());
CBitmap *pOldBit=MemDC_ShowMain.SelectObject(&pBmp_MainshowP1); //MemDC_ShowMain.SelectObject(&pBmp_MainshowP1);
MemDC_ShowMain.FillSolidRect(pRect_MainshowP1,GetSysColor(COLOR_3DFACE));

for(i=0;i<L;i++) //main
{
for(j=0;j<L;j++)
{
y1 = up + Dy*j;
y2 = y1 + Dy;
x1 = left + Dx*i;
x2 = x1+Dx;
Rect.left=(int)(x1+0.5);
Rect.right=(int)(x2+0.5);
Rect.top=(int)(y1+0.5);
Rect.bottom=(int)(y2+0.5);

v_power = p_Buf[i*L+j]/max_p;
pos = ((int)(v_power*COLOUR_NUM))%COLOUR_NUM;

vColor=Colour_Table[pos];
pBrush=new CBrush(vColor);
pDC->FillRect(Rect,pBrush);
delete pBrush;

}
}
pDC_MainshowP1->BitBlt(0,0,W,H,&MemDC_ShowMain,0,0,SRCCOPY);


...全文
334 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
zyb083 2014-12-10
  • 打赏
  • 举报
回复
引用 23 楼 Sandrer 的回复:
同样的道理,你先把数据处理成一段连续的颜色数据 然后自己建立一个bmp,再把颜色数据直接复制到位图上 接着建立一个内存 dc,把 bmp 选入内存 dc 中 最后直接把内存 dc 的内容整个 bitblt 到前端窗口 dc 中 这样操作内存比你操作 gdi 对象要快很多的
嗯,谢谢,我试试看。
Sandrer 2014-12-08
  • 打赏
  • 举报
回复
引用 22 楼 zyb083 的回复:
谢谢大家的帮助,现在画图的速度已经提上去了。 主要还是因为在for循环里不断的生成和销毁CBrush对象,造成速度太慢。现在的解决办法是在初始化时生成所有颜色对应的CBrush,然后在for循环中只需要调用即可。
同样的道理,你先把数据处理成一段连续的颜色数据 然后自己建立一个bmp,再把颜色数据直接复制到位图上 接着建立一个内存 dc,把 bmp 选入内存 dc 中 最后直接把内存 dc 的内容整个 bitblt 到前端窗口 dc 中 这样操作内存比你操作 gdi 对象要快很多的
zyb083 2014-12-07
  • 打赏
  • 举报
回复
谢谢大家的帮助,现在画图的速度已经提上去了。 主要还是因为在for循环里不断的生成和销毁CBrush对象,造成速度太慢。现在的解决办法是在初始化时生成所有颜色对应的CBrush,然后在for循环中只需要调用即可。
zyb083 2014-12-07
  • 打赏
  • 举报
回复
引用 19 楼 Sandrer 的回复:
楼主你应该先去了解下 bmp 结构 图像类型的文件中都会有一段连续的数据来表示颜色值 如果是8位的bmp, 则数据段中每个字节表示一个像素颜色(只有黑白) 16位的bmp, 每两个字节代表一个像素颜色 24位的bmp, 每三个字节代表一个像素颜色 32位的bmp, 每四个字节代表一个像素颜色, 其中一个字节为透明度 那么你可以分析一下发送给你的数据流, 看它们是不是一段代表颜色的数据 如果是的话, 那就简单了 找到 bmp 中代表数据段的地方, 直接整段数据 copy 过去, 再把 bmp 选入 dc 不就完事了
谢谢,说的很详细。我的数据实际上是float类型的,需要自己产生对应的伪彩色图。
vocanicy 2014-12-06
  • 打赏
  • 举报
回复
你的内存DC和Bitmap不要每次都创建、销毁,这样效率太低了
Sandrer 2014-12-06
  • 打赏
  • 举报
回复
楼主你应该先去了解下 bmp 结构 图像类型的文件中都会有一段连续的数据来表示颜色值 如果是8位的bmp, 则数据段中每个字节表示一个像素颜色(只有黑白) 16位的bmp, 每两个字节代表一个像素颜色 24位的bmp, 每三个字节代表一个像素颜色 32位的bmp, 每四个字节代表一个像素颜色, 其中一个字节为透明度 那么你可以分析一下发送给你的数据流, 看它们是不是一段代表颜色的数据 如果是的话, 那就简单了 找到 bmp 中代表数据段的地方, 直接整段数据 copy 过去, 再把 bmp 选入 dc 不就完事了
zyb083 2014-12-06
  • 打赏
  • 举报
回复
引用 17 楼 pcradio 的回复:
1.视频播放快,是因为用了硬件加速,图形处理是靠GPU计算的,而GDI完全靠的是CPU,速度自然没法比,你可以考虑用DX或OpenGL来绘制 2.如果你每次更新显示都是调用Invalidate()整个窗口都要刷新的,你可以考虑计算矩形块的脏矩形,然后InvalidateRect()来刷新
谢谢,应该是这个原因,准备看看openGL
阿源是少年 2014-12-05
  • 打赏
  • 举报
回复
1.视频播放快,是因为用了硬件加速,图形处理是靠GPU计算的,而GDI完全靠的是CPU,速度自然没法比,你可以考虑用DX或OpenGL来绘制 2.如果你每次更新显示都是调用Invalidate()整个窗口都要刷新的,你可以考虑计算矩形块的脏矩形,然后InvalidateRect()来刷新
一桶姜山 2014-12-05
  • 打赏
  • 举报
回复
用gdi对象来一个个点画随便怎么做都是很慢的,要直接写内存才会提高速度 好像是用dib什么什么函数获得位图内存信息,然后直接写
hubo86915531 2014-12-05
  • 打赏
  • 举报
回复
有一种方式 创建一张位图200*200的位图(24位) 然后依次给位图每个点赋值 再用DC直接加载位图 就是不知道速度会不会比你这个快一些
hubo86915531 2014-12-05
  • 打赏
  • 举报
回复
CBrush brush(vColor); pDC->FillRect(Rect,&brush); 这样试试
hubo86915531 2014-12-05
  • 打赏
  • 举报
回复
CBrush brush(vColor); pDC->FillRect(Rect,&brush); 这样试试
zyb083 2014-12-05
  • 打赏
  • 举报
回复
引用 6 楼 lx624909677 的回复:
把计算画图信息的代码写在另外一个线程里,比如点计算之类的,在OnPaint中,只写绘图代码试试
引用 7 楼 wxhxj0268 的回复:
顶楼上,使用双线程起码在绘图数据未完成时可使用老数据绘制,刷新速度可以不受影响。
嗯,这样应该是可以提高窗口中图像的刷新速度。但是真实的图像的更新速度并没有变。 现在的情况是,别人大概会每秒给我传过来10个200×200的图像,需要连续的显示在界面上。也就是说,计算画图信息的线程也要达到这样的速度。 不知道有没有什么更好的画图方法,可以更快一些。大家平时用MFC画图一般都是什么速度啊。
jiuzhu_dongfeng 2014-12-05
  • 打赏
  • 举报
回复
是啊,播放视频一秒也要十多帧的,绘图应该不会这么慢。
zyb083 2014-12-05
  • 打赏
  • 举报
回复
引用 5 楼 likfeng 的回复:
慢的原因主要是因为pBrush反复创建销毁造成的
试了下一直用一个颜色来画确实快了不少。感觉反复创建销毁是慢了一些,但是由于每个像素点的颜色都不一样。不知道还有没有其他好的办法。 能不被先把所有颜色的画笔都创建了,然后再循环里只调用,一共有几千个颜色吧。不知道这样靠谱不?
zyb083 2014-12-05
  • 打赏
  • 举报
回复
引用 5 楼 likfeng 的回复:
慢的原因主要是因为pBrush反复创建销毁造成的
试了下一直用一个颜色来画确实快了不少。感觉反复创建销毁是慢了一些,但是由于每个像素点的颜色都不一样。不知道还有没有其他好的办法。 能不被先把所有颜色的画笔都创建了,然后再循环里只调用,一共有几千个颜色吧。不知道这样靠谱不?
zyb083 2014-12-05
  • 打赏
  • 举报
回复
引用 5 楼 likfeng 的回复:
慢的原因主要是因为pBrush反复创建销毁造成的
试了下一直用一个颜色来画确实快了不少。感觉反复创建销毁是慢了一些,但是由于每个像素点的颜色都不一样。不知道还有没有其他好的办法。 能不被先把所有颜色的画笔都创建了,然后再循环里只调用,一共有几千个颜色吧。不知道这样靠谱不?
笨笨仔 2014-12-04
  • 打赏
  • 举报
回复
顶楼上,使用双线程起码在绘图数据未完成时可使用老数据绘制,刷新速度可以不受影响。
lx624909677 2014-12-03
  • 打赏
  • 举报
回复
把计算画图信息的代码写在另外一个线程里,比如点计算之类的,在OnPaint中,只写绘图代码试试
likfeng 2014-12-03
  • 打赏
  • 举报
回复
慢的原因主要是因为pBrush反复创建销毁造成的
加载更多回复(4)

16,472

社区成员

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

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

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