A simple screen capture libraryBy Rim van Wersch, January 23 2006 |
This screen capture library allows you to create screenshots and a simple movie capture from your Managed DirectX applications. It currently only encodes the movie into AVI file format and the code for creating these movies is still under development to iron out the bugs and increase performance. So this is very much a work in progress and we'd appreciate some feedback if anyone tries it, so we can work towards a decent library for this functionality.
Please note that the test results with the movie capture library have shown that its performance heavily depends on your hardware. It can achieve very decent results (about 1200 fps) on a P4 dual core machine, but it has also showed very bad performance (10 fps) on a Centrino laptop. So with that said, use it at your own risk
Here's the code for the capture class, which shows how we create still screenshots and read the backbuffer into a Bitmap, which is used for generating the AVI movie. We wanted the code to be as flexible as possible, without the need for creating a lockable backbuffer, so we've had some issues with obtaining the data from it. It turned out that buffering the data from the backbuffer onto a surface in system memory increased performance from 10fps to about 400fps. Quite puzzling that this works out, since device.GetRenderTargetData should reportedly be very slow, so feedback on this would be much appreciated.
////// Static utility class for invoking static utility functions /// public class ScreenCapture { ? ?public static void SaveImage(Device device, string fileName, ImageFileFormat format) ? ?{ ? ? ? ?using( Surface backbuffer = device.GetBackBuffer( 0, 0, BackBufferType.Mono ) ) ? ? ? ?{ ? ? ? ? ? ?SurfaceLoader.Save( fileName, format, backbuffer ); ? ? ? ?} ? ?} ? ? ? ?private Surface bufferSurface; ? ?public ScreenCapture( ) ? ?{ ? ?} ? ?public Bitmap SaveToBitmap(Device device) ? ?{ ? ? ? ?using( Surface backbuffer = device.GetBackBuffer( 0, 0, BackBufferType.Mono ) ) ? ? ? ?{ ? ? ? ? ? ? ? ? ? ? ? ?if (bufferSurface == null) ? ? ? ? ? ?{ ? ? ? ? ? ? ? ?CreateBufferSurface(device, backbuffer.Description); ? ? ? ? ? ?} ? ? ? ? ? ?else if (!bufferSurface.Description.Equals( backbuffer.Description )) ? ? ? ? ? ?{ ? ? ? ? ? ? ? ?// bufferSurface is disposed on device reset, so don't worry about this ? ? ? ? ? ?} ? ? ? ? ? ?device.GetRenderTargetData( backbuffer, bufferSurface ); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ?using(GraphicsStream gStr = SurfaceLoader.SaveToStream( ImageFileFormat.Bmp, bufferSurface )) ? ? ? ?{ ? ? ? ? ? ?return (Bitmap)Bitmap.FromStream( gStr ); ? ? ? ? ? ? ? ? ? ? ? ?} ? ?} ? ?private void CreateBufferSurface( Device device, SurfaceDescription desc ) ? ?{ ? ? ? ?bufferSurface = device.CreateOffscreenPlainSurface( desc.Width, desc.Height, desc.Format, Pool.SystemMemory ); ? ? ? ? ? ? ? ?} ? ?public void Dispose() ? ?{ ? ? ? ?if (bufferSurface != null) ? ? ? ?{ ? ? ? ? ? ?bufferSurface.Dispose(); ? ? ? ? ? ?bufferSurface = null; ? ? ? ?} ? ?} }
Files for this article
Filename | Size |
? ScreenCapture-v0.2b.zip | 289.5 KB |