Unity c #, screenshot and save to file as jpg

I am trying to take a screencapture and save it to a jpg file. I follow this example.


This is what I have so far:

    string jpgFile = Application.persistentDataPath + "/scrn-1.jpg";
    Texture2D tex = new Texture2D (Screen.width, Screen.height);
    tex.ReadPixels (new Rect(0, 0, Screen.width, Screen.height), 0, 0);
    tex.Apply ();
    var bytes = tex.EncodeToJPG();
    Destroy (tex);
    System.IO.File.WriteAllBytes(jpgFile, bytes);


I found that running this in Unity on iOS gives me:

JPEG parameter structure mismatch: library thinks size is 372, caller expects 360

However, if I change the conversion to tex.EncodeToPNG (); and change the filename to .png, everything works fine. I'm not sure how any help can be obtained. Thank you.


source to share

2 answers

I found this one that allows you to save it as a .jpg. I usually just use the capture screen and save as .png.

Here you go:

using UnityEngine;
using System.Collections;

public class HiResScreenShots : MonoBehaviour {
    public int resWidth = 2550; 
    public int resHeight = 3300;

    private bool takeHiResShot = false;

    public static string ScreenShotName(int width, int height) {
        return string.Format("{0}/screenshots/screen_{1}x{2}_{3}.png", 
                             width, height, 

    public void TakeHiResShot() {
        takeHiResShot = true;

    void LateUpdate() {
        takeHiResShot |= Input.GetKeyDown("k");
        if (takeHiResShot) {
            RenderTexture rt = new RenderTexture(resWidth, resHeight, 24);
            camera.targetTexture = rt;
            Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
            RenderTexture.active = rt;
            screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
            camera.targetTexture = null;
            RenderTexture.active = null; // JC: added to avoid errors
            byte[] bytes = screenShot.EncodeToPNG();
            string filename = ScreenShotName(resWidth, resHeight);
            System.IO.File.WriteAllBytes(filename, bytes);
            Debug.Log(string.Format("Took screenshot to: {0}", filename));
            takeHiResShot = false;


If you just want some kind of picture, I highly recommend this:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour 
    void OnMouseDown() 


Simple and effective.



Actually I really needed something like this today, but didn't save it. Unity does not provide us with a default method to immediately return an image as a byte, so I solved my problem.

internal class ScreenCapture : MonoBehaviour
    internal byte[] Image = null;

    internal void SaveScreenshot()

    private IEnumerator SaveScreenshot_ReadPixelsAsynch()
        //Wait for graphics to render
        yield return new WaitForEndOfFrame();

        //Create a texture to pass to encoding
        Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);

        //Put buffer into texture
        texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);

        //Split the process up--ReadPixels() and the GetPixels() call inside of the encoder are both pretty heavy
        yield return 0;

        byte[] bytes = texture.EncodeToPNG();
        Image = bytes;

        //Tell unity to delete the texture, by default it seems to keep hold of it and memory crashes will occur after too many screenshots.



internal static ScreenCapture Capture;

if (Capture == null)
    Capture = Camera.main.gameObject.AddComponent<ScreenCapture>();

// if you wish to save:
System.IO.File.WriteAllBytes("filename.png", Capture.Image);




All Articles