Unity內截圖實現
阿新 • • 發佈:2019-01-01
Unity內一般有三種截圖的方法:
- Application.CaptureScreenshot
- Texture2D.ReadPixels
- 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);
}
}
比較
- CaptureScreenshot在截全屏時很方便,不過官方已經不推薦了。
- Texture2D.ReadPixels適合定製尺寸的截圖,通過一個Rect型別來指定範圍, 左下角為(0, 0),傳入螢幕尺寸可以截全屏。
- RenderTextures截圖可以指定攝像機,適合截圖時遮蔽UI等情況。
如有錯誤,歡迎指出。
email:dxmdxm1992#gmail.com