Unity抓取相机截图/抓取屏幕截图
抓取相机截图
思路
在项目中,我们会遇到需要抓取相机截图,然后作为UI背景的需求。一般的思路如下:
- 创建一个RenderTexture,临时赋值给相机的targetTexture用于渲染相机内容
- 手动调用相机进行渲染,然后将RenderTexture从相机上取下,这样我们就得到了该相机的快照
- 在UI上添加RawImage组件,通过脚本将RenderTexture赋值给RawImage的Texture即可。
处理将该渲染纹理作为UI背景,我们还可以充分利用该纹理做一些屏幕后处理特效加工。
代码实现
// 相机截图
RenderTexture CameraRT;
/// <summary>
/// 抓取相机截图
/// </summary>
/// <returns></returns>
public RenderTexture CaptureCamera()
{
if (CameraRT != null)
{
//释放缓冲区
RenderTexture.ReleaseTemporary(CameraRT);
}
int rtW = Screen.width;
int rtH = Screen.height;
///-- 抓取相机截图
Camera camera = this.gameObject.GetComponent<Camera>();
// 建一个RenderTexture对象
CameraRT = RenderTexture.GetTemporary(rtW, rtH, 0);
// 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
camera.targetTexture = CameraRT;
camera.Render();
// 重置相关参数,以使用 camera 继续在屏幕上显示
camera.targetTexture = null;
return CameraRT;
}
抓取屏幕截图
原理
与相机截图不一样的是,该屏幕截图会抓取所有渲染之后的结果(包含所有相机、UI渲染结果),相当于在手机上直接截图屏幕。
由于该截图需要获取到所有渲染,所以我们需要在所有渲染完毕后调用方法,因此会利用到携程的WaitForEndOfFrame对象。
WaitForEndOfFrame:等待,直到该帧结束,在渲染所有摄像机和 GUI 之后,在屏幕上显示该帧之前。
这里我们用到的是Texture2D的ReadPixels()方法来采集渲染信息,而没有采用RenderTexture,有需要的话可以使用Graphics.Blit(Texture source, RenderTexture dest);
将源纹理复制到目标渲染纹理中。
代码实现:
/// <summary>
/// 抓取整个屏幕截图
/// </summary>
/// <returns></returns>
public Texture2D CaptureScreen()
{
//用屏幕的宽度和高度创建一个新的纹理
Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
StartCoroutine(CaptureScreenshot(texture));
return texture;
}
IEnumerator CaptureScreenshot(Texture2D texture)
{
//只在每一帧渲染完成后才读取屏幕信息
yield return new WaitForEndOfFrame();
//读取屏幕像素信息并存储为纹理数据
texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
texture.Apply();// 这一句必须有,像素信息并没有保存在2D纹理贴图中
}