zoukankan      html  css  js  c++  java
  • 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,毕竟内存数据处理起来要方便的多。

    作者:小时了了
    原创文章,欢迎转载,但请以链接形式注明本文地址.
  • 相关阅读:
    ihaiLjEUSx
    表达式的逆波兰式转化模板
    运算表达式求值模板
    程序员花式拜年脚本
    vbs脚本实现自动打字祝福&搞笑
    MFC实现红黑砖块
    vbs脚本实现qq定时发消息(初级)
    打包java程序生成exe
    webpack配置
    vue路由
  • 原文地址:https://www.cnblogs.com/xrunning/p/3647046.html
Copyright © 2011-2022 走看看