使用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
        );
    }
}

参考:experts-exchange.com

posted on 2014-10-02 18:03  xiaowy  阅读(4987)  评论(1编辑  收藏  举报