1. 程式人生 > >Unity內截圖實現

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

優點:簡單,可以快速地擷取某一幀的畫面、全屏截圖

缺點:
1. 不能針對攝像機截圖
2. 定製大小截圖不方便

using UnityEngine;
using System.Collections;

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

Texture2D.ReadPixels

根據一個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

跟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等情況。

如有錯誤,歡迎指出。

email:dxmdxm1992#gmail.com