Unity内截屏实现

Unity内一般有三种截屏的方法:

  1. Application.CaptureScreenshot
  2. Texture2D.ReadPixels
  3. RenderTextures

图片保存地址一般设为: Application.persistentDataPath + “/screen1.png”

参考persistentDataPath的文档说明:The value is a directory path where data expected to be kept between runs can be stored. When publishing on iOS and Android, persistentDataPath will point to a public directory on the device.


下面我们来看具体的实现:

Application.CaptureScreenshot

文档上已将此方法标记为 Obsolete 。
https://docs.unity3d.com/ScriptReference/Application.CaptureScreenshot.html

优点:简单,可以快速地截取某一帧的画面、全屏截图

缺点:
1. 不能针对摄像机截图
2. 定制大小截图不方便

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    void OnMouseDown() {
        Application.CaptureScreenshot(Application.persistentDataPath + "/CaptureScreenshot.png");
    }
}

Texture2D.ReadPixels

https://docs.unity3d.com/ScriptReference/Texture2D.ReadPixels.html

根据一个Rect来截取指定范围的屏幕,左下角为(0,0)

创建一个空纹理,读取屏幕像素,保存为文件

using UnityEngine;
using System.Collections;
using System.IO;

public class ScreenTexture2DReadPixels : MonoBehaviour {

    [ContextMenu("Start ScreenShoot")]
    public void StartScreenShoot() {
        StartCoroutine(ScreenShoot(Application.persistentDataPath + "/ReadPixels.png"));
    }

    private IEnumerator ScreenShoot(string filePath)
    {
        //Wait for graphics to render
        yield return new WaitForEndOfFrame();

        //Create a texture to pass to encoding
        Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);

        //Put buffer into texture
        texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);

        //Split the process up--ReadPixels() and the GetPixels() call inside of the encoder are both pretty heavy
        yield return 0;

        byte[] bytes = texture.EncodeToPNG();

         //Save our test image (could also upload to WWW)
        File.WriteAllBytes(filePath, bytes);

        //Tell unity to delete the texture, by default it seems to keep hold of it and memory crashes will occur after too many screenshots.
        DestroyObject(texture);
    }
}

RenderTextures

https://docs.unity3d.com/ScriptReference/RenderTexture.html

跟Texture2D.ReadPixels相比,不同处在于ReadPixels读的是某个相机渲染的像素

using System.Collections;
using System.IO;
using UnityEngine;

public class RenderTextures : MonoBehaviour {

    [ContextMenu("Start ScreenShoot")]
    public void StartScreenShoot()
    {
        StartCoroutine(ScreenShoot(Application.persistentDataPath + "/RenderTextures.png"));
    }

    private IEnumerator ScreenShoot(string filePath)
    {
        //Wait for graphics to render
        yield return new WaitForEndOfFrame();

        RenderTexture rt = new RenderTexture(Screen.width, Screen.height, 24);
        Texture2D screenShot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);

         //Render from all!
        foreach (Camera cam in Camera.allCameras)
        {
            cam.targetTexture = rt;
            cam.Render();
            cam.targetTexture = null;
        }

        RenderTexture.active = rt;
        screenShot.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
        Camera.main.targetTexture = null;

         //Added to avoid errors
        RenderTexture.active = null; 
        Destroy(rt);

        //Split the process up--ReadPixels() and the GetPixels() call inside of the encoder are both pretty heavy
        yield return 0;

        byte[] bytes = screenShot.EncodeToPNG();
        File.WriteAllBytes(filePath, bytes);
    }
}

比较

  1. CaptureScreenshot在截全屏时很方便,不过官方已经不推荐了。
  2. Texture2D.ReadPixels适合定制尺寸的截图,通过一个Rect类型来指定范围, 左下角为(0, 0),传入屏幕尺寸可以截全屏。
  3. RenderTextures截屏可以指定摄像机,适合截图时屏蔽UI等情况。

参考:http://wiki.unity3d.com/index.php/ScreenCapture


如有错误,欢迎指出。

email:dxmdxm1992#gmail.com

blog: http://blog.csdn.net/david_dai_1108

猜你喜欢

转载自blog.csdn.net/david_dai_1108/article/details/77509194