- Home /
Can't capture Multiple Screenshots in one Second
Hey
I am having trouble saving Multiple Screenshots really fast in Unity using Application.CaptureScreenshot
It appears that the Capture Screenshot function is only saving out one file per second
It is reporting multiple inputs second and each of them have a different filename so to avoid overwriting the previous screenshots. However Unity only seems to be saving the last screenshot recorded in that second.
It is not exactly needed to save them this fast, but it would be nice to figure out how to make this work in the event I ever do need to have them saved quickly.
Code:
public static class ScreenshotHelper
{
static DateTime m_LastTime = new DateTime(0);
static int m_LastNumber = 0;
[MenuItem("Tools/Save Screenshot &P")]
public static void TakeScreenshot()
{
if (m_LastTime.Approximately(DateTime.Now)) { m_LastNumber++; } else { m_LastTime = DateTime.Now; m_LastNumber = 0; }
string t_Filename = Application.productName + " - " + m_LastTime.ToString("yyyy-MM-dd HH-mm-ss");
if (m_LastNumber != 0) { t_Filename = t_Filename + " (" + m_LastNumber + ")"; }
string t_FilePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\" + t_Filename + ".png";
Debug.Log("Screenshot Saved to \"" + t_FilePath + "\"");
Application.CaptureScreenshot(t_FilePath);
}
static bool Approximately(this DateTime a_Self, DateTime a_CompareTo)
{
if (a_Self.Year != a_CompareTo.Year) { return false; }
if (a_Self.Month != a_CompareTo.Month) { return false; }
if (a_Self.Day != a_CompareTo.Day) { return false; }
if (a_Self.Hour != a_CompareTo.Hour) { return false; }
if (a_Self.Minute != a_CompareTo.Minute) { return false; }
if (a_Self.Second != a_CompareTo.Second) { return false; }
return true;
}
}
Debug Log Output:
Actual File Output:
Answer by Yujingping · Aug 09, 2016 at 06:18 PM
Hi there. I have successfully reproduced your issue in Unity 5.4.0f3 and the response is exactly what you have described. Perhaps this is a bug or so and lets consider reporting it to the official. However just to solve your problem, I think you may try ReadPixels which allows you to dynamically control the parameters of the screenshot. Here is my example code:
private IEnumerator TakeScreenshot ()
{
yield return new WaitForEndOfFrame ();
Texture2D screenShot = new Texture2D (Screen.width, Screen.height, TextureFormat.RGB24, false);
screenShot.ReadPixels (new Rect (0, 0, Screen.width, Screen.height), 0, 0);
screenShot.Apply ();
byte[] bytes = screenShot.EncodeToPNG ();
int index = ImageNumber + 1;
ImageNumber++;
string fileName = Application.persistentDataPath + "/Screenshot" + index + ".png";
System.IO.File.WriteAllBytes (fileName, bytes);
}
I have tried this and it works pretty fine. Please note that don't miss "yield return new WaitForEndOfFrame ();" at the first line in the Coroutine. Otherwise it may not work as predicted. Do not take screenshots too frequently on mobile platforms. I have experienced crash when doing so. Also please note that if you wanna to control the size, you may compress the PNG file by "screenShot.Compress ();". However this does not work on iOS for some unknown reason. If you have further questions please feel free to contact me. GL & HF!
This worked great for me, except for the fact that it requires to be on a monobehaviour for the coroutine to work.
Here is my final version I came up with Here on GitHub Gist
For anyone who happens to come across this, it works on PC fine, might need some tweaking for other keyboard layouts and/or platforms