我已经得到了一个位图句柄hBmp,在下面的函数中有2个参数,我不知如何通过已知的hBmp来赋值
BOOL DrawDibDraw(
  HDRAWDIB hdd,             
  HDC hdc,                  
  int xDst,                 
  int yDst,                 
  int dxDst,                
  int dyDst,                
  LPBITMAPINFOHEADER lpbi,  //如何通过已知的hBmp来赋值?
  LPVOID lpBits,            //如何通过已知的hBmp来赋值?
  int xSrc,                 
  int ySrc,                 
  int dxSrc,                
  int dySrc,                
  UINT wFlags               
);

解决方案 »

  1.   

    CBitmap* pBmp=CBitmap::FromHandle(hBmp);
    BITAMP bmp;
    pBmp->GetBitmap(&bmp);
    //自己根据bmp构造BITMAPHEADER
    pBmp->GetBitmapBits
      

  2.   

    能再具体点吗,我对这个不太熟,怎么得到这2个参数?
    LPBITMAPINFOHEADER lpbi, 
    LPVOID lpBits
      

  3.   

    BITMAPINFOHEADER,MSDN中有说明
    LPVOID lpBits
    实际上就是一个缓冲区
      

  4.   

    怎么根据bmp构造BITMAPHEADER,MSDN只是介绍了BITMAPHEADER的结构啊?
      

  5.   

    ZeroMemory(pbminfo, sizeof BITMAPINFOHEADER);
    pbminfo->biSize = sizeof BITMAPINFOHEADER;
    pbminfo->biWidth =bmp.bmWidth;
    pbminfo->biHeight = bmp.bmHeight;
    pbminfo->biPlanes = bmp.bmPlanes;
    pbminfo->biBitCount = bmp.bmBitsPixel ;
    pbminfo->biCompression = BI_RGB;
    pbminfo->biSizeImage = (3*pbminfo->biWidth+3)/4*4*abs(pbminfo->biHeight);
    PBYTE pBuffer=(PBYTE)bmp.bmBits;
      

  6.   

    谢谢 DentistryDoctor(雅克医生(潜心修内功)) 
    不过LPVOID lpBits=?
      

  7.   

    PBYTE pBuffer=(PBYTE)bmp.bmBits是作什么用的?
      

  8.   

    我这样用对不对啊?HBITMAP    hBitmap = CopyScreenToBitmap(m_tragetRect);//获得屏幕截图的位图句柄
    CBitmap*   pBmp=CBitmap::FromHandle(hBitmap);
    BITMAP bmp;
    pBmp->GetBitmap(&bmp);
       
    LPBITMAPINFOHEADER pbminfo = new BITMAPINFOHEADER;
    ZeroMemory(pbminfo, sizeof (BITMAPINFOHEADER));
    pbminfo->biSize = sizeof (BITMAPINFOHEADER);
    pbminfo->biWidth =bmp.bmWidth;
    pbminfo->biHeight = bmp.bmHeight;
    pbminfo->biPlanes = bmp.bmPlanes;
    pbminfo->biBitCount = bmp.bmBitsPixel ;
    pbminfo->biCompression = BI_RGB;
    pbminfo->biSizeImage = (3*pbminfo->biWidth+3)/4*4*abs(pbminfo->biHeight);
    PBYTE pBuffer=(PBYTE)bmp.bmBits;if(m_hDrawDib) 
    {
       DrawDibRealize(m_hDrawDib, pDC->GetSafeHdc(), TRUE );
       DrawDibDraw( m_hDrawDib, pDC->GetSafeHdc(),
    tragetRect.left, tragetRect.top, tragetRect.Width(), tragetRect.Height(),
    pbminfo, (LPVOID)(pBuffer),
    0, 0, 1024, 768,
    DDF_BACKGROUNDPAL );
    }可是运行后没有显示屏幕的截图啊:(
      

  9.   

    是将原存放图象数据的内存首地址赋值给pBuffer指针。
      

  10.   

    是不是要LPVOID lpBits=pBuffer+?,该加什么?
      

  11.   

    还有我发现
    PBYTE pBuffer=(PBYTE)bmp.bmBits;//这里得到的bmp.bmBits为0x00000000,但其他的象bmp.bmWidth等都得到值了,为甚吗?源程序如上
      

  12.   

    使用DrawDibDraw是为了对图象快速操作,图象数据做为数组,图象处理直接对数组操作,不需要SetPixelV等,然后通过DrawDibDraw显示,因此其参数需要这个数组的首址,同时还需要BITMAPINFOHEADER,知道该图象多大,位深等信息。你要用这个显示HBITMAP就违反其初衷了,因为需要从HBITMAP转成图象数据:
    如你上面的代码得到HBITMAP,BITMAPINFOHEADER以后,需要
    COLORREF lpbuf = new COLORREF[bmp.bmWidth * bmp.bmHeight];
    HDC hDC=GetDC(hWnd);
    GetDIBits(hDC,hBitmap,0,bmp.bmHeight,lpbuf,pbminfo,DIB_RGB_COLORS);
    ReleaseDC(hWnd,hDC);然后把lpbuf作为参数,DrawDibDraw最后一个参数换成DDF_HALFTONE试试看。
      

  13.   

    错了,应该是COLORREF* lpbuf = new COLORREF[bmp.bmWidth * bmp.bmHeight];
      

  14.   

    谢谢ringphone(临风),照你说的改了(不过我没改参数 DDF_HALFTONE,你为什么说要还成DDF_HALFTONE?)
    还有我的本意是想截取屏幕的图像,然后将其缩放到相应的窗口中显示,如果直接用GDI的StretchBlt太耗CPU了,所以就想用DrawDib,可是DrawDibDraw又要什么LPBITMAPINFOHEADER 作参数,所以我就把截取的屏幕转换成HBITMAP,不知道你有什么建议。
      

  15.   

    要改成DDF_HALFTONE是因为我不能确定你的问题是否真出在bmp.bmBits上。截取屏幕图像的话好象只能是HBITMAP,必须通过GetDIBits得到数据。LPBITMAPINFOHEADER其实除了宽,高,位深等信息外,其他都是固定的。
    DrawDibDraw的图象缩放其速度及效果的确比StretchBlt好,但有个BUG,如果图象宽高比很大,既图象很长或很高,超过某一比例DrawDibDraw就显示不正常了,最好的方法是自己写缩放代码。当然你如果只用来截取屏幕图像是不会碰到这问题的。
      

  16.   

    用CreateDIBSection创建的位图, bm.bmBits不会为NULL, 所以不需要用GetDIBits这样耗时函数.
      

  17.   

    我发现DrawDibDraw是可以降低一点CPU的使用率,可还是挺高的,是不是因为我截取的屏幕区域较大啊,我试
    了,如果是一个小的区域CPU使用率就很低,可是我需要截取并放大显示一块较大的屏幕区域,那有什么好办法呢?
    我试过将截取的区域分割成很多小的区域,轮流对他们进行屏幕拷贝放大显示,可为了保证截屏画面的流畅,就要求对每个区域的拷贝次数要多,最好20帧/秒,但这样CPU的使用率又冲上去了(100%)请教各位有什么高见!