我尝试了各种变体:http://wiki.unity3d.com/index.php/ScreenCapture 毕竟,简单的Application.Capturescreenshot(...)是最不了解的。
请告诉我,如何在没有任何滞后的情况下拍摄截图? Android上的很多游戏都具有thiis功能,因此并非不可能。
答案 0 :(得分:6)
拍摄时滞后的原因是指您尝试同时执行所有步骤时没有 等待强>每一步后。要解决此问题,您执行一个操作并等待多个帧,然后执行下一个操作,然后再次等待。如果您决定在游戏过程中保存图片,请使用线程保存图片。 EncodeToPNG()
是另一个问题但我稍后会讨论另一个解决方案。
如果您想拍摄屏幕截图然后在游戏运行时立即显示,则下面的代码很好。 它将以正确的方式拍摄,然后花费大约1.5秒来保存文件。
IEnumerator screenShotCoroutine()
{
yield return new WaitForEndOfFrame();
string path = Application.persistentDataPath + "/DrukaloScreenshot.png";
Texture2D screenImage = new Texture2D(Screen.width, Screen.height);
//Get Image from screen
screenImage.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
screenImage.Apply();
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
//Convert to png(Expensive)
byte[] imageBytes = screenImage.EncodeToPNG();
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
//Create new thread then save image to file
new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(100);
File.WriteAllBytes(path, imageBytes);
}).Start();
}
如果你想拍照并且不需要立即显示图片,你可以将图片保存为原始 Texture2D
,然后如果您想稍后访问/加载/显示图片,您可以读取 文件,然后将其转换为 PNG 。这样做的原因是EncodeToPNG()
非常昂贵,因此如果您不需要立即拍照,则无需将其转换为png。当你需要 png 时,你可以 。所以现在我们可以将它保存为&#34; .t2D &#34;然后加载它并将加载的图像转换为&#34; .png &#34;。
另存为Texture2D&#34; .t2D &#34;
IEnumerator screenShotCoroutine()
{
yield return new WaitForEndOfFrame();
string path = Application.persistentDataPath + "/DrukaloScreenshot.t2D";
Texture2D screenImage = new Texture2D(Screen.width, Screen.height);
//Get Picture
screenImage.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
screenImage.Apply();
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
byte[] rawData = screenImage.GetRawTextureData();
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
//Create new thread then save image
new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(100);
File.WriteAllBytes(path, rawData);
}).Start();
}
然后,当您确实需要图像时,请加载Texture2D&#34; .t2D &#34;然后将其转换为&#34; .png &#34;然后删除旧的&#34; .t2D &#34;。
IEnumerator screenShotCoroutine()
{
string path = Application.persistentDataPath + "/DrukaloScreenshot.t2D";
string newPath = Application.persistentDataPath + "/DrukaloScreenshot.png";
Texture2D screenImage = new Texture2D(Screen.width, Screen.height);
byte[] rawData = null;
//Create new thread then Load image
new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(100);
rawData = File.ReadAllBytes(path);
}).Start();
//Wait for a long time
for (int i = 0; i < 9; i++)
{
yield return null;
}
//Put loaded bytes to Texture2D
screenImage.LoadRawTextureData(rawData);
//Wait for a long time
for (int i = 0; i < 9; i++)
{
yield return null;
}
screenImage.Apply();
//Wait for a long time
for (int i = 0; i < 9; i++)
{
yield return null;
}
//convert to png
byte[] pngByte = screenImage.EncodeToPNG();
//Wait for a long time
for (int i = 0; i < 9; i++)
{
yield return null;
}
//Do whatever you want with the png file(display to screen or save as png)
//Create new thread and Save the new png file, then Delete Old image(DrukaloScreenshot.t2D)
new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(100);
File.WriteAllBytes(newPath, pngByte); //Save the new png file(DrukaloScreenshot.png)
File.Delete(path); //Delete old file (DrukaloScreenshot.t2D)
}).Start();
}
答案 1 :(得分:2)
Application.CaptureScreenshot()
一般都很慢,更快的方法是使用Texture2D
并使用ReadPixels()
函数读取屏幕上的所有像素,而不是编码和保存纹理到了硬盘。
这是此方法的一个示例:
Texture2D screenShot = new Texture2D(Screen.width, Screen.height);
screenShot.ReadPixels(new Rect(0,0,Screen.width,Screen.height),0,0);
screenShot.Apply();
byte[] bytes = tex.EncodeToPNG();
Object.Destroy(tex);
File.WriteAllBytes(Application.dataPath + "/../myScreenShot.png", bytes);
要获得完整参考,您可以使用Unity脚本参考页面here。