Untiy3D 截屏功能
为了保存VR一体机中的Unity的渲染画面,需要实现一个截屏的功能.
下面是我查询到的几个方法.记录一下.
利用Unity的API
Unity提供了一个现成的API
Application.CaptureScreenshot(imagename)
优点:
- 这个API使用起来非常方便.可以快速地截取某一帧的画面[全屏截图]
缺点:
- 但是在移动平台上就显得比较吃力,因为它会消耗很大的CPU,所以在移动端截屏会发现一段时间的卡顿现象.
- 不能真对某个摄像机截图,无法局部截图
注意事项:
- 不同平台存放的路径有差别.
Application.CaptureScreenshot(screencapture.png);
if(Application.platform==RuntimePlatform.Android || Application.platform==RuntimePlatform.IPhonePlayer)
imagePath=Application.persistentDataPath;
else if(Application.platform==RuntimePlatform.WindowsPlayer)
imagePath=Application.dataPath;
else if(Application.platform==RuntimePlatform.WindowsEditor) {
imagePath=Application.dataPath;
imagePath= imagePath.Replace("/Assets",null);
}
imagePath = imagePath + "/screencapture.png";
使用Texture2d类下的相关方法
通过读取屏幕缓存然后转化为PNG图片进行截图.截图的存储路径可以自己设置.
/// <summary>
/// Captures the screenshot2.
/// </summary>
/// <returns>The screenshot2.</returns>
/// <param name="rect">Rect.截图的区域,左下角为o点</param>
Texture2D CaptureScreenshot2(Rect rect)
{
// 先创建一个的空纹理,大小可根据实现需要来设置
Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24,false);
// 读取屏幕像素信息并存储为纹理数据,
screenShot.ReadPixels(rect, 0, 0);
screenShot.Apply();
// 然后将这些纹理数据,成一个png图片文件
byte[] bytes = screenShot.EncodeToPNG();
string filename = Application.dataPath + "/Screenshot.png";
System.IO.File.WriteAllBytes(filename, bytes);
Debug.Log(string.Format("截屏了一张图片: {0}", filename));
// 最后,我返回这个Texture2d对象,这样我们直接,所这个截图图示在游戏中,当然这个根据自己的需求的。
return screenShot;
}
注意:
截全屏:
CaptureScreenshot2( new Rect( Screen.width*0f, Screen.height*0f, Screen.width*1f, Screen.height*1f));
截中间4分之1:
CaptureScreenshot2( new Rect( Screen.width*0.25f, Screen.height*0.25f, Screen.width*0.5f, Screen.height*0.5f));
具体方法介绍,看Texture2d类
缺点:
- 这个方法也不要到实现针对某个相机的截图的功能
- 不过关键接口已经出现了,它就是
Texture2d.ReadPixels()
针对某个相机进行截图
如何实现对某个相机进行截屏
使用的一个新的类就是 RenderTexture
.
/// <summary>
/// 对相机截图。
/// </summary>
/// <returns>The screenshot2.</returns>
/// <param name="camera">Camera.要被截屏的相机</param>
/// <param name="rect">Rect.截屏的区域</param>
Texture2D CaptureCamera(Camera camera, Rect rect)
{
// 创建一个RenderTexture对象
RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);
// 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
camera.targetTexture = rt;
camera.Render();
//ps: --- 如果这样加上第二个相机,可以实现只截图某几个指定的相机一起看到的图像。
//ps: camera2.targetTexture = rt;
//ps: camera2.Render();
//ps: -------------------------------------------------------------------
// 激活这个rt, 并从中中读取像素。
RenderTexture.active = rt;
Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24,false);
screenShot.ReadPixels(rect, 0, 0);// 注:这个时候,它是从RenderTexture.active中读取像素
screenShot.Apply();
// 重置相关参数,以使用camera继续在屏幕上显示
camera.targetTexture = null;
//ps: camera2.targetTexture = null;
RenderTexture.active = null; // JC: added to avoid errors
GameObject.Destroy(rt);
// 最后将这些纹理数据,成一个png图片文件
byte[] bytes = screenShot.EncodeToPNG();
string filename = Application.dataPath + "/Screenshot.png";
System.IO.File.WriteAllBytes(filename, bytes);
Debug.Log(string.Format("截屏了一张照片: {0}", filename));
return screenShot;
}