拍照时滞后的原因是当您尝试同时执行所有步骤没有 等待 strong> 在每一步之后。要解决此问题,您执行一个操作并等待许多帧,然后执行下一个操作,然后再次等待。如果您决定在游戏过程中保存图片,请使用线程来保存图片。 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();
}
如果您要拍照并且不需要立即显示图像,您可以将图片保存为raw Texture2D,然后当您想要稍后访问/加载/显示图片,您可以从 file 中读取,然后稍后将其转换为 PNG。这样做的原因是EncodeToPNG() 非常昂贵,所以如果您不需要立即使用图片,则无需将其转换为 png。 只有在您真正需要 png 时才能这样做。所以现在我们可以将它保存为“.t2D”然后加载它并将加载的图像转换为“.png”。
另存为 Texture2D ".t2D"
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“.t2D”,然后将其转换为“.png”,然后删除旧的“”。 t2D”。
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();
}