Capture screenshot to texture, memory issue

Hi guys,
I’m working on a project and i want that display the screenshot to GUI texture.
I have tow buttons, one for take screenshot and one for show it.

This is TakeScreenShot button:

using UnityEngine;
using System.Collections;
using System.IO;
    public class ScreenShot : MonoBehaviour {
    	
        void OnMouseUp ()
        {
        audio.Play ();
    	string filePath = Application.persistentDataPath + "/screenshot.png";
    	Application.CaptureScreenshot (filePath);
    	}
    	
    }

This is ShowScreenShot button:

using UnityEngine;
using System.IO;
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;

public class ShowScreenShot : MonoBehaviour {

	private bool ShowGui = false;

	void OnMouseDown () {
		ShowGui = true;
	}
	
	void OnGUI()
	{

		
		if (ShowGui==true){
		
		var fileName = Path.Combine( Application.persistentDataPath, "screenshot.png" );
		var bytes = File.ReadAllBytes( fileName );
        var screenshot = new Texture2D( 0, 0, TextureFormat.ATF_RGB_DXT1, false );
        screenshot.LoadImage( bytes );
			
		GUI.DrawTexture (new Rect(Screen.width/2 - 200, Screen.height/2 - 150,400,300), screenshot);
		if (GUI.Button (new Rect(0,0,100,50),"Close"))
			{
				ShowGui = false;
			}
	}
}
}

After i show my screenshot on GUI texture, My Ram use raise very fast and Unity crash.
I’ve searched around, and i know it is memory issue but i don’t know how to solve that problem.

Can any one of you guys can help me.

Thanks alot.

It is probably due to your OnGUI function constantly creating the filename, reading all the bytes of the screenshot and then creating a texture every call. You should switch it so that you have an if(GUI.Button) statement around the saving of a screenshot and the loading of a screenshot code. This will make it only store/load a screenshot when you press the button. The GUI call will then only be rendering the screenshot plus the two buttons every call.

Thanks for your comment, i'm just a noob, i understand what you say but i can't describe it in C#, i only know java and start to try some C# because most plugin require C#. Thanks again.

1 Answer

1

You’re releading the image to memory every frame. You shouldn’t read the resource in OnGUI, unless you cache it. Use this code:

public class ShowScreenShot : MonoBehaviour {
 
    private bool ShowGui = false;
    private Texture2D _screenshot = null;
    private Texture2D screenshot {
        get {
            if (_screenshot == null) {
                var fileName = Path.Combine( Application.persistentDataPath, "screenshot.png" );
                var bytes = File.ReadAllBytes( fileName );
                _screenshot = new Texture2D( 0, 0, TextureFormat.ATF_RGB_DXT1, false );
                _screenshot.LoadImage( bytes );
            }
            return _screenshot;
        }
    }

    void OnMouseDown () {
       ShowGui = true;
    }
 
    void OnGUI()
    {
        if (ShowGui==true){ 
            GUI.DrawTexture (new Rect(Screen.width/2 - 200, Screen.height/2 - 150,400,300), screenshot);
            if (GUI.Button (new Rect(0,0,100,50),"Close"))
            {
                ShowGui = false;
            }
        }
    }
}

Thanks @tbkn for your answer, your code works fine. But i need to show the lastest screenshot taken by TakeScreenShot button (user can take as much as they want). How can i do it? Thanks.

Thanks to all, i got it. You save my day.