x


How to save a picture (take screenshot) from a camera in game?

it is possible for a camera to take a picture and save it as jpg? I could not find on google or unity.

more ▼

asked Jul 21 '10 at 08:54 AM

crasyboy42 gravatar image

crasyboy42
229 21 21 23

Dec 12 '12 at 01:53 PM Cawas

By the way, asset store has now a script to do it and store it in iOS and Android gallery. Great responsive developer behind it, I've used it and approved: http://u3d.as/content/ryansoft/gallery-screenshot/4pz

May 16 at 04:51 PM Cawas
(comments are locked)
10|3000 characters needed characters left

7 answers: sort voted first

Yes, it is possible. And there's even a couple of different approaches you could use:

There's a script for taking screenshots on the Unifycommunity Wiki: TakeScreenshot

The method used to do this is: Application.CaptureScreenshot, [EDIT: Which also has a parameter superSize for high resolution screenshots using an integer multiple of the current screen resolution]

There's also an approach to do [-high resolution-] screenshots [EDIT: with any arbitrary resolution]. I have a script which is based on the script posted in Submitting featured content. This will take a screenshot and store it to disk when you press the key "k" (you could change the key by changing the code). You have to attach the script to a camera for it to work:

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", 
                             Application.dataPath, 
                             width, height, 
                             System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
    }

    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);
            camera.Render();
            RenderTexture.active = rt;
            screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
            camera.targetTexture = null;
            RenderTexture.active = null; // JC: added to avoid errors
            Destroy(rt);
            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;
        }
    }
}

It also shouldn't be too hard to post those screenshots to combine this with the example code in the WWWForm-documentation to post those screenshots to a server.

more ▼

answered Jul 21 '10 at 11:12 AM

jashan gravatar image

jashan
10.3k 25 43 117

I dont now if this is a common issue, but i had to use the function in the LateUpdate call, some of my objects, which i create with Graphics.DrawMesh() were not on the screenshot.

Jul 21 '10 at 04:28 PM Case23

Good point - I've changed the code to use LateUpdate() instead of Update() to be on the safe side.

Jul 21 '10 at 10:42 PM jashan

Hi,Jashan i dont want to save the screenshot,but i just wanted to display it to a smaller view beside my game,can you help me

Dec 29 '11 at 08:41 AM wenhua

If you have Unity Pro, you could use render textures for this purpose. That won't have your GUI included (if you're using UnityGUI), though. Another thing that might be possible is saving the screenshot to disk first, then loading it, then creating a texture from it. Haven't tried that, yet, but theoretically it should work (at least in environments where you have disk access).

Jan 06 '12 at 09:48 AM jashan

@Cawas: Not sure if the parameter "superSize : int = 0" was added later to Application.CaptureScreenshot, or whether I missed it when I wrote the original answer. In most cases, using CaptureScreenshot is probably the best way to do it. An advantage of the other script may be that you can use any resolution, not just multiples of the current screen resolution. I'll edit the wording to reflect that change.

Dec 11 '12 at 01:58 PM jashan
(comments are locked)
10|3000 characters needed characters left
more ▼

answered Jul 21 '10 at 08:58 AM

Julian Glenn gravatar image

Julian Glenn
2.6k 5 12 47

(comments are locked)
10|3000 characters needed characters left

Yes. Take a look at JPEG Encoding in Native Unity JavaScript by Matthew Wegner, Flashbang Studios.

more ▼

answered Jul 21 '10 at 01:32 PM

AliAzin gravatar image

AliAzin
2.6k 43 56 79

(comments are locked)
10|3000 characters needed characters left
  1. Create a render texture.
  2. Apply it on the camera.
  3. Reference the camera in the script
  4. Set the render texture as active RenderTexture.active
  5. Create a Texture2D to which you dump the current RenderTexture
  6. Put back the original RenderTexture.active back. Things to worry about: PNG files store alpha channels as well as any other color information. Sometimes some object might not appear because they simply have that information on it. Most of the time the Texture2D that you need has to be simply of type RGB24, not ARGB32.

Here is a code snippet that should help you:

using UnityEngine;
using System.Collections;
using System;

public class ScreenCapture : MonoBehaviour
{
    public RenderTexture overviewTexture;
    GameObject OVcamera;
    public string path = "";

    void Start()
    {
        OVcamera = GameObject.FindGameObjectWithTag("OverviewCamera");
    }

    void LateUpdate()
    {

        if (Input.GetKeyDown("f9"))
        {
            StartCoroutine(TakeScreenShot());
        }

    }

    // return file name
    string fileName(int width, int height)
    {
       return string.Format("screen_{0}x{1}_{2}.png",
                             width, height,
                             System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
    }

    public IEnumerator TakeScreenShot()
    {
        yield return new WaitForEndOfFrame();

        Camera camOV = OVcamera.camera;

        RenderTexture currentRT = RenderTexture.active;

        RenderTexture.active = camOV.targetTexture;
        camOV.Render();
        Texture2D imageOverview = new Texture2D(camOV.targetTexture.width, camOV.targetTexture.height, TextureFormat.RGB24, false);
        imageOverview.ReadPixels(new Rect(0, 0, camOV.targetTexture.width, camOV.targetTexture.height), 0, 0);
        imageOverview.Apply();

        RenderTexture.active = currentRT;


        // Encode texture into PNG
        byte[] bytes = imageOverview.EncodeToPNG();

        // save in memory
        string filename = fileName(Convert.ToInt32(imageOverview.width), Convert.ToInt32(imageOverview.height));
        path = Application.persistentDataPath + "/Snapshots/" + filename;

        System.IO.File.WriteAllBytes(path, bytes);
    }
}
more ▼

answered May 20 at 08:49 AM

Mate-O gravatar image

Mate-O
1

(comments are locked)
10|3000 characters needed characters left

Jashan code works when you play in editor, however when build and play the screen shot image was blank , was is due to render target has been changed to 'RenderTexture'?? however i tried just saving the texture without render target texture then it worked fine..:) Thank you so much for your suggestions above..:)

more ▼

answered Jan 24 '12 at 06:26 AM

abhinandan gravatar image

abhinandan
1

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3125
x106
x32

asked: Jul 21 '10 at 08:54 AM

Seen: 34433 times

Last Updated: May 20 at 08:49 AM