发布时间:2025-12-09 13:50:02 浏览次数:4
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 HDC11 target_rect.left, // X sink position12 target_rect.top, // Y sink position13 target_rect.right - target_rect.left, // Destination width14 target_rect.bottom - target_rect.top, // Destination height15 hdcMemory, // Source device HDC16 0, // X source position17 0, // Y source position18 bm.bmWidth, // Source width19 bm.bmHeight, // Source height20 SRCCOPY); // Simple copy21 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 position10 0, // Adjusted Y source position11 lpbi->biWidth, // Source width12 abs(lpbi->biHeight), // Source height13 bits, // Image data14 (LPBITMAPINFO)lpbi, // DIB header15 DIB_RGB_COLORS, // Type of palette16 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 the2 // output pin was being rotten and didn't choose our super excellent shared3 // memory DIB allocator so we have to do this slow render using boring old GDI4 // SetDIBitsToDevice and StretchDIBits. The down side of using these GDI5 // functions is that the image data has to be copied across from our address6 // space into theirs before going to the screen (although in reality the cost7 // is small because all they do is to map the buffer into their address space)
也就是说StretchDIBits比StretchBlt多消耗了从内存地址空间拷贝图像数据到GDI地址空间的时间。实际测试结果在XP和Win7系统下两者效率几乎没有区别,所以可以放心大胆的使用StretchDIBits,毕竟内存数据处理起来要方便的多。
转载于:https://www.cnblogs.com/xrunning/p/3647046.html