Unity 局部截图,包含UI

UNITY截图屏幕的时候,如果直接使用(此方法可自定义截图区域)

// 先创建一个的空纹理,大小可根据实现需要来设置

Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);

// 读取屏幕像素信息并存储为纹理数据,

screenShot.ReadPixels(rect, 0, 0);

screenShot.Apply();

会报错
有两种解决方法
一种是使用协程

yield return new WaitForEndOfFrame();
        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();

一种是在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;
        }
    }

错误的意思就是说ReadPixels是从系统缓冲区帧里找像素而不是从图框内找。
简单说就是,你的图应该先在Camera渲染完,存进缓冲之后再ReadPixels。
所以修改方法就是,把Update换成OnPostRender,这个函数只有在摄像机下才会执行,摄像机每帧渲染完执行。在Update后执行。

 

另外还有两种截图方法

使用Application类下的CaptureScreenshot方法。

/// 
    /// 截取全屏的方法包括UI
    /// 
    public void CaptureScreen()
    {
        Application.CaptureScreenshot("截取全屏.png", 0);
        Debug.Log(1);
    }

第三个方法,最牛了,可以针对某个相机进行截图。

这样的话,我就可截下,我的Avatar在游戏中场景中所看的画面了,UI界面(用一个专门的camera显示)什么的是不应该有的。要做到这一点,我们应该将分出一个camera来专门显示ui界面,用另一个camera相机来场景显示场景画面。然后,我们只对场景相机进行截屏就是了。所以这关键点就是:如何实现对某个相机进行截屏了。这里用到一个新的类是RenderTexture。

/// 
/// 对相机截图。 
/// 
/// The screenshot2.
/// Camera.要被截屏的相机
/// Rect.截屏的区域
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;
}

 

你可能感兴趣的:(UI,渲染,unity)