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
文档上已将此方法标记为 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);
}
}
比较
CaptureScreenshot在截全屏时很方便,不过官方已经不推荐了。
Texture2D.ReadPixels适合定制尺寸的截图,通过一个Rect类型来指定范围, 左下角为(0, 0),传入屏幕尺寸可以截全屏。
RenderTextures截屏可以指定摄像机,适合截图时屏蔽UI等情况。
参考:http://wiki.unity3d.com/index.php/ScreenCapture