- Home /
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.
Basically I was saying that rather than having your
void On$$anonymous$$ouseDown
and
void On$$anonymous$$ouseUp
functions, you could ins$$anonymous$$d create buttons on the screen using
if(GUI.Button(new Rect(10, 10, 100, 100), "TakeScreenshot"))
{
//save screenshot here
}
and
if(GUI.Button(new Rect(Screen.width - 110, 10, 100, 100), "DisplayScreenshot"))
{
//Load and store screenshot into a Texture2D
}
Then, your script would look something like this at the end
private byte[] bytes;
private Texture2D screenshot;
private string filePath, filename;
void OnGUI()
{
if(GUI.Button(new Rect(10, 10, 100, 100), "Take a Screenshot"))
{
audio.Play();
filePath = Application.persistentDataPath + "/screenshot.png"
Application.CaptureScreenshot(filePath);
}
if(GUI.Button(new Rect(Screen.width - 110, 10, 100, 100), "Display Screenshot"))
{
filename = Path.Combine(Application.persistentDataPath, "screenshot.png");
bytes = File.ReadAllBytes(filename);
screenshot = new Texture2D(0, 0, TextureFormat.ATF_RGB_DXT1, false);
screenshot.LoadImage(bytes);
}
if(screenshot != null)
{
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"))
{
screenshot = null;
}
}
Answer by Tomer-Barkan · Dec 14, 2013 at 02:03 PM
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.
just set _screenshot = null
whenever you take a screenshot, and the next time you try to display it, it will reload from file screenshot.png.
Your answer
Follow this Question
Related Questions
My OnGUI() Won't show the Button elements :( 0 Answers
Stretching a Texture2D to fill entire button 2 Answers
RenderTexture to Texture2D 4 Answers
GUI.Label background not working since 4.5 upgrade 1 Answer
Offset detail texture in c# 1 Answer