blog games developers documentation portfolio gallery

More in this category:

Handy Unity3D C# functions (5. screenshots)

Posted on June 16, 2014, by Richard Knol

Making a screenshot in Unity is easy. Just call Application.CaptureScreenshot() and it saves a PNG file for you. But what if you want to use the screenshot in your game or if you want to upload it to a server. You could read the saved file back in, but is a crappy solution.

It's better to just do the screenshotting yourself and have complete control over the result.

Have a look at my AssetStore packages:
SimpleLOD - simplify meshes, merge meshes and create LODs
Simple.OBJ - import .OBJ models at runtime
SimpleCollada - import Collada models at runtime
SimpleXML - import and export XML
SimpleJSON - import and export JSON
Texture2D - image manipulation (scale, rotate, crop, etc)
ListBox - Adds a listbox UI control

Take screenshot


To take a screenshot you need a Camera. If you don't provide a camera, the function will use the default main camera instead.
public static Texture2D TakeScreenshot(int width, int height, 
Camera screenshotCamera) {
if(width<=0 || height<=0) return null;
if(screenshotCamera == null) screenshotCamera = Camera.main;

Texture2D screenshot = new Texture2D(width, height, TextureFormat.RGB24, false);
RenderTexture renderTex = new RenderTexture(width, height, 24);
screenshotCamera.targetTexture = renderTex;
screenshotCamera.Render();
RenderTexture.active = renderTex;
screenshot.ReadPixels(new Rect(0, 0, width, height), 0, 0);
screenshot.Apply(false);
screenshotCamera.targetTexture = null;
RenderTexture.active = null;
Destroy(renderTex);
return screenshot;
}

We make an empty Texture2D that will hold the screen shot and a RenderTexture that will capture the camera output.
We set the RenderTexture to be the target of the camera and tell it to Render().
Next comes a bit of a weird trick. The RenderTexture is set as active and the pixels are read into the Texture2D. This is the only way I know of to obtain the contents of a RenderTexture.
The pixels are written to the Texture2D with Apply(false). False is because we don't need any mip levels. Change it to true if you do want miplevels.
The rest of the function is to clean up the mess and return the Texture2D.

Save Screenshot


This function uses the previous one to take the screenshot. Then it tests to see if it is at all possible to save a file. It checks if the filename ends with ".png" or ".jpg" and encodes the Texture2D's bytes accordingly. We then open a FileStream and write the bytes to the file. Make sure you have the namespace "using System.IO" included.
public static Texture2D TakeScreenshot(int width, int height, 
Camera screenshotCamera, string saveToFileName) {
Texture2D screenshot = TakeScreenshot(width, height, screenshotCamera);
if(screenshot != null && saveToFileName!=null) {
if(Application.platform==RuntimePlatform.OSXPlayer ||
Application.platform==RuntimePlatform.WindowsPlayer &&
Application.platform!=RuntimePlatform.LinuxPlayer
|| Application.isEditor) {
byte[] bytes;
if(saveToFileName.ToLower().EndsWith(".jpg"))
bytes = screenshot.EncodeToJPG();
else bytes = screenshot.EncodeToPNG();
FileStream fs = new FileStream(saveToFileName, FileMode.OpenOrCreate);
BinaryWriter w = new BinaryWriter(fs);
w.Write(bytes);
w.Close();
fs.Close();
}
}
return screenshot;
}


Upload Screenshot


Here we assume you are using a WWWForm to upload your screenshot. The function will add the screenshot bytes in jpg or png format to an existing form under a fieldName that you have to provide.
public static void AddScreenshotToForm(int width, int height, 
Camera screenshotCamera, WWWForm uploadForm, string fieldName, string extension) {
Texture2D screenshot = TakeScreenshot(width, height, screenshotCamera);
if(screenshot != null && fieldName!=null && uploadForm!=null) {
byte[] bytes;
string mimeType;
if(extension.ToLower()==("jpg")) {
bytes = screenshot.EncodeToJPG();
mimeType = "image/jpeg";
} else {
bytes = screenshot.EncodeToPNG();
mimeType = "image/png";
}
uploadForm.AddBinaryData(fieldName, bytes, fieldName+"."+extension, mimeType);
}
}







follow us