显示图片居然花了700ms时间,请帮我看看是怎么回事?

LinHanLao 2009-05-14 03:11:32
用如下的代码显示一个800 x 454 24bit的图片时,居然花了700ms时间(CPU主频600M)?请帮忙看看问题在哪里?

case WM_PAINT:
{
HDC hdcmem;
HBITMAP hBitmap, hOldBmp1, hOldBmp2;
BITMAP bmp;
HDC hdcBuf;
HDC hdcBmp;
RECT rc;
TCHAR msg[MAX_PATH] = {0};
DWORD RefTime = 0;


RefTime = GetTickCount();

swprintf(msg, TEXT("Paint Begin = %d\n"), RefTime);
OutputDebugString(msg);

hdc = BeginPaint(hWnd, &ps);

GetClientRect(hWnd, &rc);

if (g_bmBuffer == NULL)
g_bmBuffer = CreateCompatibleBitmap(hdc, rc.right - rc.left, rc.bottom - rc.top);

hdcBuf = CreateCompatibleDC(hdc);
hOldBmp1 = (HBITMAP)SelectObject(hdcBuf, g_bmBuffer);

//显示背景图
hdcBmp = CreateCompatibleDC(hdc);
hOldBmp2 = (HBITMAP)SelectObject(hdcBmp, g_hBitmap[BmpIndex]);


RefTime = GetTickCount();
swprintf(msg, TEXT("BitBlt Begin = %d\n"), RefTime);
OutputDebugString(msg);
BitBlt(hdcBuf, 0, 0, 800, 454, hdcBmp, 0, 0, SRCCOPY); //这里居然用了600ms,为什么会出现这种情况?
RefTime = GetTickCount();
swprintf(msg, TEXT("BitBlt End = %d\n"), RefTime);
OutputDebugString(msg);


SelectObject(hdcBmp, hOldBmp2);
DeleteDC(hdcBmp);

RefTime = GetTickCount();
swprintf(msg, TEXT("BitBlt Begin = %d\n"), RefTime);
OutputDebugString(msg);
BitBlt(hdc, 0, 0, 800, 454, hdcBuf, 0, 0, SRCCOPY);
RefTime = GetTickCount();
swprintf(msg, TEXT("BitBlt End = %d\n"), RefTime);
OutputDebugString(msg);


SelectObject(hdcBuf, hOldBmp1);
DeleteDC(hdcBuf);


EndPaint(hWnd, &ps);

RefTime = GetTickCount();
swprintf(msg, TEXT("Paint End = %d\n"), RefTime);
OutputDebugString(msg);

break;
}
...全文
308 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
soupcai 2009-06-01
  • 打赏
  • 举报
回复
楼主可以试试双缓绘图,时间肯定会少很多!
LinHanLao 2009-05-27
  • 打赏
  • 举报
回复
谢谢 shuiyan,

不好意思,上面我说错了,应该是显示控制在10ms以内,我现在就是用的预读,把图片通过DDRAW保存了,但由于DDRAW的特殊性,不能保存大量图片,
所以想用GDI的方式把图片预读到内存,显示的时候就直接从内存读取就好了。

另外我现在是做一个程序的UI,并不是做图片浏览器之类的。
shuiyan 2009-05-27
  • 打赏
  • 举报
回复
“装载图片到显示出来要在10ms以内”,可能性不大。至少你可以算出从nand读出这么大尺寸的文件需要多长时间,再加上内存中直接显示的几十毫秒,那时间长的太多了。

不如考虑第一张慢,后面的用预读方案,类似cache的方式。

从flash复制到内存就直接用文件打开、复制即可。
LinHanLao 2009-05-27
  • 打赏
  • 举报
回复
谢谢 wohuazhen,

600ms的时间确实是图片在nand flash里测出来的,当我把程序放在ram里运行的话,就只要200ms左右了
但我的目标是装载图片到显示出来要在10ms以内,看上去这种方式是达不到的??!!

另外,想请教,如何把bitmap图片先拷贝到内存?我现在是用ddraw的办法把图片copy到内存的
wohuazhen 2009-05-21
  • 打赏
  • 举报
回复
hOldBmp2 = (HBITMAP)SelectObject(hdcBmp, g_hBitmap[BmpIndex]);

BitBlt(hdcBuf, 0, 0, 800, 454, hdcBmp, 0, 0, SRCCOPY); //这里居然用了600ms,为什么会出现这种情况?


问题在于g_hBitmap[BmpIndex]是Bitmap型。
Bitmaps can be selected for memory device contexts only, and for only one device context at a time微软有这个规定,原因并没说?!可以猜猜看?

你这个Bitmap是存在nand flash里吧?
可以先把这个Bitmap先拷贝到RAM里,再测一下时间?
估计时间还是不少?但至少减掉一半吧?
-------------------------------------------------------------
以上仅供参考
风中老长 2009-05-21
  • 打赏
  • 举报
回复
呵呵,我都是直接把显存地址揪出来直接写的

这里涉及到一些参数转换,消耗掉很多很时间

如果你不嫌烦,把lcd驱动里的bitblt重写一下效果会改善很多
wjk98550328 2009-05-20
  • 打赏
  • 举报
回复
前阵子搞wince5.0也是这个问题,bitblt太慢,最后改上linux了,估计是wince的显示驱动不行,需要优化重写
LinHanLao 2009-05-18
  • 打赏
  • 举报
回复
up
SZ_Devin 2009-05-18
  • 打赏
  • 举报
回复
up
LinHanLao 2009-05-18
  • 打赏
  • 举报
回复
哪位朋友有没有碰到类似的问题呀?我现在用ddraw来显示也不绕过这个问题!
因为前面图片的处理还是需要这一过程,DDRAW只是在显示的时候才会发挥作用!
zwtchy123 2009-05-18
  • 打赏
  • 举报
回复
uping
LinHanLao 2009-05-15
  • 打赏
  • 举报
回复
请帮忙看看呀。。。。
LinHanLao 2009-05-14
  • 打赏
  • 举报
回复
顶一下
morris88 2009-05-14
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 LinHanLao 的回复:]
If the color formats of the source and destination device contexts do not match, the BitBlt function converts the source color format to match the destination format.

这段话,有没有可能对这个操作有影响???我的位图是24bit的,但LCD驱动只支持16bit的?
[/Quote]

有影响,貌似需要转换...
LinHanLao 2009-05-14
  • 打赏
  • 举报
回复
用16bit的位图测试了,第一个BitBlt()还是需要460ms左右,第二个BitBlt()的时间在10ms以下了,

第一个BitBlt()不只是简单的内存 copy ???
LinHanLao 2009-05-14
  • 打赏
  • 举报
回复
If the color formats of the source and destination device contexts do not match, the BitBlt function converts the source color format to match the destination format.

这段话,有没有可能对这个操作有影响???我的位图是24bit的,但LCD驱动只支持16bit的?
LinHanLao 2009-05-14
  • 打赏
  • 举报
回复
91program:
OutputDebugString的影响应该不会这么大,我后一个BitBlt()花的时间才几十毫秒
91program 2009-05-14
  • 打赏
  • 举报
回复
调整一下顺序,这样会更准确的。
swprintf(msg, TEXT("BitBlt Begin = %d\n"), RefTime);
OutputDebugString(msg);
RefTime = GetTickCount();
BitBlt(hdcBuf, 0, 0, 800, 454, hdcBmp, 0, 0, SRCCOPY); //这里居然用了600ms,为什么会出现这种情况?
RefTime = GetTickCount();
swprintf(msg, TEXT("BitBlt End = %d\n"), RefTime);
OutputDebugString(msg);

LZ再检测一下,看看时间是多少?
理论上应该不需要这么久,BitBlt只是内存copy的过程。

19,518

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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