使用bitblt比DrawImage有更好的性能
using AForge.Video.DirectShow; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace HongYing.Test { public partial class BitBltTester : Form { private VideoCaptureDevice videoSource; public BitBltTester() { InitializeComponent(); #if GDIPlus SetStyle(ControlStyles.OptimizedDoubleBuffer, true); //默认启动双缓冲 SetStyle(ControlStyles.DoubleBuffer, true); SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景. #endif var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); videoSource = new VideoCaptureDevice(videoDevices[1].MonikerString); videoSource.NewFrame += _videoSource_NewFrame; videoSource.Start(); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); #if GDIPlus if (frame != null) { e.Graphics.DrawImage(frame, ClientRectangle); } #else #endif } public enum TernaryRasterOperations : uint { SRCCOPY = 0x00CC0020, SRCPAINT = 0x00EE0086, SRCAND = 0x008800C6, SRCINVERT = 0x00660046, SRCERASE = 0x00440328, NOTSRCCOPY = 0x00330008, NOTSRCERASE = 0x001100A6, MERGECOPY = 0x00C000CA, MERGEPAINT = 0x00BB0226, PATCOPY = 0x00F00021, PATPAINT = 0x00FB0A09, PATINVERT = 0x005A0049, DSTINVERT = 0x00550009, BLACKNESS = 0x00000042, WHITENESS = 0x00FF0062, CAPTUREBLT = 0x40000000 //only if WinVer >= 5.0.0 (see wingdi.h) } Bitmap frame; private const int SRCCOPY = 0xCC0020; void _videoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs) { frame = (Bitmap)eventArgs.Frame.Clone(); #if GDIPlus Invalidate(); #else Bitmap sourceBitmap = frame; Graphics sourceGraphics = Graphics.FromImage(frame); Graphics destGraphics = CreateGraphics(); IntPtr destDC = destGraphics.GetHdc(); IntPtr destCDC = CreateCompatibleDC(destDC); IntPtr oldDest = SelectObject(destCDC, IntPtr.Zero); IntPtr sourceDC = sourceGraphics.GetHdc(); IntPtr sourceCDC = CreateCompatibleDC(sourceDC); IntPtr sourceHB = sourceBitmap.GetHbitmap(); IntPtr oldSource = SelectObject(sourceCDC, sourceHB); int success = StretchBlt(destDC, 0, 0, Width, Height, sourceCDC, 0, 0, sourceBitmap.Width, sourceBitmap.Height, (int)TernaryRasterOperations.SRCCOPY); SelectObject(destCDC, oldDest); SelectObject(sourceCDC, oldSource); DeleteObject(destCDC); DeleteObject(sourceCDC); DeleteObject(sourceHB); destGraphics.ReleaseHdc(); sourceGraphics.ReleaseHdc(); #endif eventArgs.Frame.Dispose(); } [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] public static extern IntPtr CreateCompatibleDC(IntPtr hdc); [System.Runtime.InteropServices.DllImport("gdi32.dll")] private static extern int BitBlt( IntPtr hdcDest, // handle to destination DC (device context) int nXDest, // x-coord of destination upper-left corner int nYDest, // y-coord of destination upper-left corner int nWidth, // width of destination rectangle int nHeight, // height of destination rectangle IntPtr hdcSrc, // handle to source DC int nXSrc, // x-coordinate of source upper-left corner int nYSrc, // y-coordinate of source upper-left corner System.Int32 dwRop // raster operation code ); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] public static extern IntPtr SelectObject(IntPtr hdc, IntPtr obj); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] public static extern void DeleteObject(IntPtr obj); [DllImport("gdi32", EntryPoint = "StretchBlt")] public static extern int StretchBlt( IntPtr hdc, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, int dwRop ); } }