Fast real time Screen Capture (60 fps or better)

时间:2015-05-24 20:45:06

标签: c# screenshot capture screen-capture slimdx

I have tried using GDI+ and SlimDX to capture the screen.

Surprisingly, the good old GDI+ was faster for me, for unknown reasons (averaging 38-50ms for a screenshot).

SlimDX is slower, averaging 40-80ms (it spikes really often) and also, _device.GetFrontBufferData(0, _surface); makes a memory leak that I don't know how to fix.

What can I use to take fast screenshots in real time ? If this makes any difference, the purpose of this will be to save it in a .avi later on, or possibly stream that sequence of images in real time.

Below I show the code I am using for both GDI+ (commented out) and SlimDX. You will need a reference to SlimDX.dll for this to work

using SlimDX;
using SlimDX.Direct3D9;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;

namespace DxCapture
{
    public partial class Form1 : Form
    {
        static Device _device;
        static AdapterInformation _adapterInfo;
        static Surface _surface;
        static Bitmap _bitmap = new Bitmap(1920, 1080);

        public Form1()
        {
            InitializeComponent();
            timer1.Start();
            DoubleBuffered = true;

            Direct3D _direct3D9 = new Direct3D();
            _adapterInfo = _direct3D9.Adapters.DefaultAdapter;
            PresentParameters present_params = new PresentParameters();
            present_params.Windowed = true;
            present_params.SwapEffect = SwapEffect.Discard;

            _device = new Device(new Direct3D(), 0, DeviceType.Hardware,
                (IntPtr)0, CreateFlags.SoftwareVertexProcessing, 
                present_params);
            _surface = Surface.CreateOffscreenPlain(_device,
                _adapterInfo.CurrentDisplayMode.Width, 
               _adapterInfo.CurrentDisplayMode.Height, 
               Format.A8R8G8B8, Pool.SystemMemory);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Stopwatch _watch = Stopwatch.StartNew();

            // -------- Method 1: SlimDX -------- 
            _device.GetFrontBufferData(0, _surface);
            _bitmap.Dispose();
            _bitmap = new Bitmap(Surface.ToStream(_surface,
                ImageFileFormat.Bmp, new Rectangle(0, 0, 1920, 1080)));
            this.BackgroundImage = (Image)_bitmap;

            // --------  Method 2: GDI+ -------- 
            //_bitmap.Dispose();
            //_bitmap = new Bitmap(1920, 1080);
            //using (Graphics g = Graphics.FromImage(_bitmap))
            //    g.CopyFromScreen(0, 0, 0, 0, new Size(1920, 1080));
            //this.BackgroundImage = (Image)_bitmap;

            _watch.Stop();
            Console.WriteLine(_watch.Elapsed.TotalMilliseconds);
        }
    }
}

0 个答案:

没有答案