在Unity3D中截取屏幕截图,没有滞后

Dru*_*alo 2 c# android screenshot screen unity-game-engine

我尝试了各种变体:http: //wiki.unity3d.com/index.php/Scr​​eenCapture Afterall,简单的Application.Capturescreenshot(...)是最不了解的.

请告诉我,如何在没有任何滞后的情况下拍摄截图?Android上的很多游戏都有thiis功能,所以这并非不可能.

Pro*_*mer 6

事业滞后而拍照是当你尝试执行在同一时间的所有步骤无需 等待每一步之后.要解决此问题,请执行一个操作并等待多个帧然后执行下一个操作,然后再次等待.如果您决定在游戏过程中保存图片,请使用Thread保存图片. 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();
}
Run Code Online (Sandbox Code Playgroud)

如果你想拍照,你是不是需要显示的图像向右走,你可以将图片保存为原料 Texture2D,那么当你想以后访问/负载/显示图片,你可以阅读从它的文件然后转换以后再到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();
    }
Run Code Online (Sandbox Code Playgroud)

然后当你真正需要图像时,加载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();
}
Run Code Online (Sandbox Code Playgroud)