StretchBlt和StretchDIBits

StretchBlt:从源矩形中复制一个位图到目标矩形,必要时按目标设备设置的模式进行图像的拉伸或压缩,如果目标设备是窗口DC,则意味着在窗口绘制位图,大致的使用代码如下:

 1 void DrawImage(HDC hdc, HBITMAP hbm, const RECT target_rect)

 2 {

 3     HDC hdcMemory = ::CreateCompatibleDC(hdc);

 4     HBITMAP old_bmp = (HBITMAP)::SelectObject(hdcMemory, hbm);

 5 

 6     BITMAP bm = { 0 };

 7     ::GetObject(hbm, sizeof(bm), &bm);

 8 

 9     ::StretchBlt(

10         hdc,                              // Target device HDC

11         target_rect.left,                   // X sink position

12         target_rect.top,                    // Y sink position

13         target_rect.right - target_rect.left,    // Destination width

14         target_rect.bottom - target_rect.top,    // Destination height

15         hdcMemory,                               // Source device HDC

16         0,                                // X source position

17         0,                               // Y source position

18         bm.bmWidth,                        // Source width

19         bm.bmHeight,                        // Source height

20         SRCCOPY);                                // Simple copy

21 

22     ::SelectObject(hdcMemory, old_bmp);

23     ::DeleteObject(hdcMemory);

24 }

 StretchDIBits:该函数将DIB(设备无关位图)中矩形区域内像素使用的颜色数据拷贝到指定的目标矩形中,如果目标设备是窗口DC,同样意味着在窗口绘制位图,大致的使用代码如下:

 1 void DrawImage(HDC hdc, LPBITMAPINFOHEADER lpbi, void* bits, const RECT target_rect)

 2 {

 3     ::StretchDIBits(

 4         hdc,                                    // Target device HDC

 5         target_rect.left,                       // X sink position

 6         target_rect.top,                        // Y sink position

 7         target_rect.right - target_rect.left,   // Destination width

 8         target_rect.bottom - target_rect.top,   // Destination height

 9         0,                                      // X source position

10         0,                                      // Adjusted Y source position

11         lpbi->biWidth,                       // Source width

12         abs(lpbi->biHeight),                 // Source height

13         bits,                                   // Image data

14         (LPBITMAPINFO)lpbi,                     // DIB header

15         DIB_RGB_COLORS,                         // Type of palette

16         SRCCOPY);                               // Simple image copy 

18 }

简单的讲,StretchBlt操作的是设备相关位图是HBITMAP句柄,StretchDIBits操作的是设备无关位图是内存中的RGB数据。

DirectShow示例代码中的CDrawImage类提供了FastRender和SlowRender两个函数用于渲染视频图像,FastRender用的StretchBlt,SlowRender用的StretchDIBits,其中SlowRender的注释是这样写的:

1 // This is called when there is a sample ready to be drawn, unfortunately the

2 // output pin was being rotten and didn't choose our super excellent shared

3 // memory DIB allocator so we have to do this slow render using boring old GDI

4 // SetDIBitsToDevice and StretchDIBits. The down side of using these GDI

5 // functions is that the image data has to be copied across from our address

6 // space into theirs before going to the screen (although in reality the cost

7 // is small because all they do is to map the buffer into their address space)

也就是说StretchDIBits比StretchBlt多消耗了从内存地址空间拷贝图像数据到GDI地址空间的时间。实际测试结果在XP和Win7系统下两者效率几乎没有区别,所以可以放心大胆的使用StretchDIBits,毕竟内存数据处理起来要方便的多。

 

 

 

 

 

你可能感兴趣的:(bit)