CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  图形处理/算法

逐点描绘太慢的问题

楼主sboom(+-LingCh-+)(爱美人不爱VC)2005-06-03 17:57:52 在 VC/MFC / 图形处理/算法 提问

我因为用了其他图像处理的程序库,现在返回的是一个图像点阵数组  
  unsigned   char*   pData;  
  知道里面是   m行n列的象素数据,每个象素占3个字节(和BMP点阵差不多)  
  现在我要在窗体上显示出来,用的是  
  for(i=0;i<m;i++)  
  {  
      for(j=0;j<n;j++)  
      {  
          pDC->SetPixel(i,j,RGB(pData[i*n+j*3+2],pData[i*n+j*3+1],pData[i*n+j*3+0]));  
      }  
  }  
  结果显示速度太慢,CPU占用也高  
   
  已经尝过用双缓冲,结果也慢。  
  我的双缓冲的显示代码如下  
  CDC   MemDC;  
  CBitmap   MemBitmap;  
  MemDC.CreateCompatibleDC(NULL);  
  MemBitmap.CreateCompatibleBitmap(pDC,1000,1000);  
  CBitmap   *pOldBit=MemDC.SelectObject(&MemBitmap);  
  MemDC.FillSolidRect(0,0,1000,1000,pDC->GetBkColor   ());  
   
  std::list<IplImage*>::iterator   itimg=(*it)->m_imgs.begin   ()   ;  
  while(itimg!=(*it)->m_imgs.end   ())//迭代每一个图  
  {  
  IplImage   *img=*itimg;  
   
  /*for(i=0;i<img->height   ;i++)  
  {  
  for(j=0;j<img->width   ;j++)  
  {  
  ::SetPixel   (MemDC.GetSafeHdc   (),xDraw+j,yDraw+img->height   -i,RGB(img->imageData   [i*img->widthStep   +j*3+2],img->imageData[i*img->widthStep   +j*3+1],img->imageData[i*img->widthStep   +j*3+0]));  
  }  
  }*/  
   
   
  yDraw+=img->height   +20;  
  itimg++;  
  }  
  //将内存中的图拷贝到屏幕上进行显示  
  pDC->BitBlt(0,0,1000,1000,&MemDC,0,0,SRCCOPY);  
  //绘图完成后的清理  
  MemBitmap.DeleteObject();  
  MemDC.DeleteDC();  
   
  ///////////////////////////////////////////  
  有什么好办法显示出来可以快一点?  
  有什么好办法显示出来可以快一点?  
  有什么好办法显示出来可以快一点? 问题点数:100、回复次数:9Top

1 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2005-06-03 18:04:24 得分 50

逐点绘制当然慢  
   
  你自己知道这个图像的格式,很容易就可以知道位图的格式  
  把它转换成为位图的格式,然后用位图操作来显示  
   
  转换的操作是内存操作,速度很快  
  画点操作是GDI操作慢,是内存和显存之间的操作,由于需要做一系列初始化,数据交换,复原操作,因此速度相对于内存之间的直接数据转换来手,速度的差异非常的大,主要差在初始化和复原操作上。  
  转换到位图后,同样也是GDI操作,但是是一次性的初始化,然后进行内存和显存之间多次的数据交换操作,和一次恢复操作。和逐点绘制相比,节约了很多次的初始化和恢复操作  
  速度可以提升很多Top

2 楼sboom(+-LingCh-+)(爱美人不爱VC)回复于 2005-06-03 18:20:32 得分 0

问题是位图在内存中格式是怎样啊?我知道那个库返回的图像格式但不知道怎样转换到CBitmap   CImage这些类啊。尝试过写到硬盘在用CImage::LoadImage读入,因为有IO操作更慢了。Top

3 楼ukyo1(**)回复于 2005-06-03 18:24:59 得分 0

用CreateBitmap创建24位位深度的HBITMAP,这样它的内存布局就与你的数据类似。不要用CreateCompatibleBitmap  
  用函数GetDIBits获取HBITMAP的原始内存内存,写一个设置函数,用内存复制的方法将位图数据直接复制过去,如果嫌C++代码效率不高,甚至可以用汇编、MMX指令来优化。  
  注意你的程序是三个字节一个一个像素,而24位的HBITMAP是4个字节一个像素,所以不能直接拷贝所有数据。Top

4 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2005-06-03 18:30:29 得分 0

有一个如何组织bitmap图的例子,就在csdn以前出的光盘里面  
  dibtoddb,ddbtodib等等  
   
  网上有一个例子:  
  http://www.pcdog.com/p/html/20041127/271120042696_1.htmTop

5 楼ukyo1(**)回复于 2005-06-03 18:31:22 得分 50

另外一个办法是用函数CreateDIBitmap,同样要注意内存布局问题,在MSDN里说的都很详细,楼主先研究一下,有不清楚的再问.Top

6 楼ukyo1(**)回复于 2005-06-03 18:32:56 得分 0

方法2创建出来的是一个与hdc兼容的位图,不限于24位色。Top

7 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2005-06-03 18:36:42 得分 0

如何获得当前屏幕上的位图的格式,可以如下:  
   
  hDC   =   CreateDC("DISPLAY",NULL,NULL,NULL);  
  iBits   =   GetDeviceCaps(hDC,   BITSPIXEL)   *   GetDeviceCaps(hDC,   PLANES);  
  DeleteDC(hDC);  
  if   (iBits   <=   1)  
   wBitCount   =   1;    
  else   if   (iBits<=   4)  
   wBitCount   =   4;    
  else   if   (iBits<=   8)  
   wBitCount   =   8;  
  else   if   (iBits   <=   24)  
   wBitCount   =   24;   //计算调色板大小  
  这样知道了每个象素占据的字节数目,类似的其他参数也都可以通过调用GetDeviceCaps来获得的  
  Top

8 楼ukyo1(**)回复于 2005-06-03 18:44:07 得分 0

我想这个程序最好抛开屏幕格式,否则太复杂了。  
  我的第二种方法应该不错,而且也兼顾了屏幕格式。Top

9 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2005-06-03 18:46:04 得分 0

copy一段csdn上网友的关于dib和ddb的说明:  
   
  1/   DIB一般用于位图文件(*.BMP),而DDB一般在程序运行中使用  
  2/   SetDIBits()它是将DIB位图转换为DDB位图。比如说你想显示一个BMP位图文件,你就  
  可以先从文件头结构中读出位图的大小,然后按照这个尺寸创建一个空位图句柄,再分配  
  一块内存,将位图文件中的位数据读到这块内存中。(注意,这个位数据就是DIB格式的)  
  然后再调用SetDIBits()函数,空位图句柄对应HBITMAP参数,内存地址对应LPVOID参  
  数。成功返回之后,空位图句柄中位图的图像就和文件中的一样了。你可以拿这个句柄  
  代入象BitBlt()之类的函数中进行各种操作。这个句柄就是DDB位图句柄。此时,调用前分配的内存块已经没用了,可以释放。  
      GetDIBits()函数的功能与SetDIBits()相反,它是将你从屏幕或其它途径获取的DDB  
  位图转换为DIB位图。转换后的DIB位数据将保存在LPVOID所指向的内存中。如果你再填写  
  一个正确的BITMAPINFO结构,那么建立位图文件就很容易了。  
    建立位图文件还有一些细节,太多了。。。。   如果实在不行的话,给俺来封信,我们再  
  详细的讨论一下。  
  Top

相关问题

  • 5460太慢了
  • jbuilder4 太慢了!!!!
  • ActiveFrom太慢了!!!
  • java 太慢???
  • procedure太慢
  • 太慢了!!!太慢了!!!太慢了!!!太慢了!!!
  • zju 1163 太慢
  • textbox反应太慢?
  • MSHFlexGrid刷新太慢
  • EPOC运行太慢

关键词

  • 内存
  • 转换
  • 函数
  • 数据
  • 图像
  • null
  • 操作
  • itimg
  • 逐点
  • memdc

得分解答快速导航

  • 帖主:sboom
  • happy__888
  • ukyo1

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo