参考链接:https://blog.csdn.net/qq_33337811/article/details/69421936
参考链接:https://www.jianshu.com/p/460803bbd5a9
第一种:使用ScreenCapture进行截屏,只能截全屏,不针对相机
/// <summary>
///第一种: unity自带的全屏截图
/// </summary>
public void OneShot()
{
// path= Application.streamingAssetsPath + "/ScreenShot/";
// if (!Directory.Exists(path))
// {
// Directory.CreateDirectory(path);
// }
var url = path + "OneShot" + Time.realtimeSinceStartup.ToString() + ".png";
ScreenCapture.CaptureScreenshot(url);
Application.OpenURL(path);
}
第二种:利用Texture2D读取屏幕像素进行截图,可以自定义屏幕范围大小
/// <summary>
/// 第二种:利用屏幕像素进行截图
/// </summary>
/// <returns>The screenshot2.</returns>
/// <param name="rect">Rect.截图的区域,左下角为o点</param>
private Texture2D CaptureScreenshot2(Rect rect,string url)
{
// 先创建一个的空纹理,大小可根据实现需要来设置
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();
Destroy(screenShot);
System.IO.File.WriteAllBytes(url, bytes);
return screenShot;
}
第三种:利用相机进行截图,可以针对某一个或某几个相机重叠进行截图
/// <summary>
/// 对相机截图。
/// </summary>
/// <returns>The screenshot2.</returns>
/// <param name="camera">Camera.要被截屏的相机</param>
/// <param name="rect">Rect.截屏的区域</param>
private Texture2D CaptureCamera(Camera camera, Rect rect,string url)
{
// 创建一个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;
Destroy(rt);
// 最后将这些纹理数据,成一个png图片文件
byte[] bytes = screenShot.EncodeToPNG();
System.IO.File.WriteAllBytes(url, bytes);
return screenShot;
}
出现问题:
在使用第二种方式截图时会报:ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame.
这个数据错误意思是:图片 应该先在Camera渲染完,存进缓冲之后再ReadPixels。
解决方式有两种:
一种是使用协程:
第二种是:在OnPostRender里处理
bool isScreenShot = false;
private void OnPostRender()
{
if (isScreenShot)
{
Rect rect = new Rect(0, 0, Screen.width, Screen.height);
// 先创建一个的空纹理,大小可根据实现需要来设置
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();
print("isScreenShot "+ bytes.Length);
isScreenShot = false;
}
}
注意:OnPostRender,这个函数只有在摄像机下才会执行,摄像机每帧渲染完执行。在Update后执行。
测试项目工程链接:https://download.csdn.net/download/qq_40120946/12023407