我因为用了其他图像处理的程序库,现在返回的是一个图像点阵数组
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();///////////////////////////////////////////
有什么好办法显示出来可以快一点?
有什么好办法显示出来可以快一点?
有什么好办法显示出来可以快一点?

解决方案 »

  1.   

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

  2.   

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

  3.   

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

  4.   

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

  5.   

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

  6.   

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

  7.   

    如何获得当前屏幕上的位图的格式,可以如下: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来获得的
      

  8.   

    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结构,那么建立位图文件就很容易了。
     建立位图文件还有一些细节,太多了。 如果实在不行的话,给俺来封信,我们再
    详细的讨论一下。