Unity实用功能之Unity截屏功能详解

4,420 阅读4分钟

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

概述

在开发过程中,经常会有一些保存图片的功能,那么这些图片是怎么保存的呢?有的直接就是一张图片,直接保存就好,而有的是一整个屏幕画面,那又该如何保存?本篇文章就来详细的介绍一下,在Unity中,如何使用截屏功能进行屏幕截取及保存图片。
在Unity中,保存图片的方法有多种:

  1. 全屏截图
  2. 自定义位置及大小截图
  3. 自定义相机以及大小截图 接下来,我们就以如下屏幕进行截图操作

image.png

功能实现

全屏截图

全屏截图我们使用的是ScreenCapture.CaptureScreenshot 使用全屏截图的优点是:简单、快速的截取某一帧的画面,能够将画面中所有主摄像机能看到的所有画面都截图保存。 缺点就是不能够规定图像大小,只能够全屏截取。截取方法如下:

ScreenCapture.CaptureScreenshot(Application.streamingAssetsPath+"/全屏截图.png", 0);

CaptureScreenshot参数1是图片保存路径以及图片名称

运行上述方法的结果为

image.png

自定义位置及大小截图

自定义截图我们使用的是Texture2D.ReadPixels,根据一个Rect类型来截取指定范围的屏幕,读取屏幕像素存储为纹理图片。此方法的优点就是截图位置和图片大小可以自己随便定义(注意不要超出屏幕范围→_→
截图时我们使用协程(IEnumerator),需要在相机渲染完一帧之后执行,所以需要用协程

//在一帧渲染之后读取屏幕信息
yield return new WaitForEndOfFrame();

接下来初始化一个Texture2D, 大小可以根据需求更改,自定义大小

Texture2D mTexture = new Texture2D((int)mRect.width, (int)mRect.height,TextureFormat.RGB24, false);

定义完Texture2D,紧接着就要根据咱们定义位置及大小进行读取屏幕像素信息并存储为纹理数据

 mTexture.ReadPixels(mRect, 0, 0);
 //应用
 mTexture.Apply();

最后是对截图文件进行保存

//将图片信息编码为字节信息
byte[] bytes = mTexture.EncodeToPNG();
//保存
System.IO.File.WriteAllBytes(Application.streamingAssetsPath+"/自定义截图.png", bytes);

在这里我们定义的方法名需要带参数是比较好的 IEnumerator CaptureByRect(Rect mRect, string mFileName)其中mRect为我们自定义的位置和大小信息。在Unity中如:new Rect(100, 100, 1024, 768)注意,此方法自定义位置,初始位置(0,0)为屏幕的左小角,所以Rect中前两位是我们自定义的起始位置,后两位为图片大小
接下来以new Rect(100, 100, 1024, 768)进行截图,截图区域如下图解

image.png 最终截图如下

image.png

自定义相机以及大小截图

自定义相机截图,使用RenderTextures,和Texture2D.ReadPixels相比,不同点在于RenderTextures可以读取某个摄像机渲染的像素。使用自定义相机截图的步骤和上一个方法差不多,唯一不同的就是需要设置一下相机渲染然后在进行数据读取截图并保存。
使用RenderTextures的优点就是截屏的时候可以指定设摄像机,适合截屏的时候屏蔽UI。
同样首先是等渲染完一帧之后在进行操作

//在一帧渲染之后读取屏幕信息
yield return new WaitForEndOfFrame();

初始化一个RenderTexture,然后将其赋值到Camera身上,并激活渲染贴图

//深度只能是【0、16、24】截不全图请修改
RenderTexture mRender = new RenderTexture((int)mRect.width, (int)mRect.height, 16);
mCamera.targetTexture = mRender;
//开始渲染
mCamera.Render();
RenderTexture.active = mRender;

定义Texture并读取像素数据

Texture2D mTexture = new Texture2D((int)mRect.width, (int)mRect.height, TextureFormat.RGB24, false);
//读取屏幕像素信息并存储为纹理数据
mTexture.ReadPixels(mRect, 0, 0);
//应用
mTexture.Apply();

读取完数据还多做一步才做,那就是释放资源,要将刚刚的渲染数据销毁释放

mCamera.targetTexture = null;
RenderTexture.active = null;
GameObject.Destroy(mRender);

最后是保存数据同上面的方法,最终截取到的图片如下

image.png

总结

本文中一共介绍了三种截屏的方法,各有优缺点

  1. 全屏截图(ScreenCapture.CaptureScreenshot) 在全屏截图的时候很方便。
  2. 自定义截图(Texture2D.ReadPixels) 适合用在自定义图片大小的时候。
  3. 自定义相机截图(RenderTextures) 截屏的时候可以指定设摄像机,适合截屏的时候屏蔽UI。

写在最后

所有分享的内容均为作者在日常开发过程中使用过的各种小功能点,分享出来也变相的回顾一下,如有写的不好的地方还请多多指教。Demo源码会在之后整理好之后分享给大家。欢迎大家相互学习进步。