Threaded Screenshot Capture
From XNAWiki
Intro
Screenshots tend to lag up the game solely because of the physical file saving aspect. The file output usually take about a second and you will definitely notice the slight pause.
Screenshot Class
Here's a class to work around that saving lag:
Note: Because of the ResolveTexture2D is being created with Bgr32 SurfaceFormat, it fixes the PNG alpha blending issue of alpha blended sprites looking brighter than they should.
using System;
using System.IO;
using System.Windows.Forms;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace LOLNAMESPACELOL
{
public class Screenshot
{
private ResolveTexture2D screenshotRT;
private string screenshotPath;
public Screenshot()
{
screenshotPath = System.Windows.Forms.Application.StartupPath + "\\screenshots";
if (!System.IO.Directory.Exists(screenshotPath))
System.IO.Directory.CreateDirectory(screenshotPath);
}
public void TakeScreenshot(GraphicsDevice device)
{
int w = device.PresentationParameters.BackBufferWidth;
int h = device.PresentationParameters.BackBufferHeight;
screenshotRT = new ResolveTexture2D(device, w, h, 1, SurfaceFormat.Bgr32);
device.ResolveBackBuffer(screenshotRT);
Thread newThread = new Thread(ScreenshotThread);
newThread.Start();
}
private void ScreenshotThread()
{
if (!screenshotRT.IsDisposed)
{
string timestampName = DateTime.Now.ToString("yyyyMMdd_HHmmss");
int i = 1;
string screenshotPostfix = "";
while (File.Exists(String.Format("{0}\\{1}{2}.png", screenshotPath, timestampName, screenshotPostfix)))
{
screenshotPostfix = " (" + i + ")";
i++;
}
string filename = String.Format("{0}\\{1}{2}.png", screenshotPath, timestampName, screenshotPostfix);
screenshotRT.Save(filename, ImageFileFormat.Png);
screenshotRT.Dispose();
}
}
}
}How to use in your game
To use this class you have to create a new Screenshot, and pass the GraphicsDevice to TakeScreenshot()
Screenshot screenShot
// other stuff you normally have here....
protected override void Initialize()
{
base.Initialize();
screenShot = new Screenshot();
}To actually take a screenshot:
screenshot.TakeScreenshot(GraphicsDevice);