一、使用Unity内置的截屏功能CaptureScreenshot直接截图保存到本地
ScreenCapture.CaptureScreenshot(Application.streamingAssetsPath + "/ScreenShot.png");
二、使用Unity内置的截屏功能CaptureScreenshotAsTexture得到Texture2D
该方案需要考虑CaptureScreenshotAsTexture只能在一个渲染帧完成后执行,相关的描述如下
To get a reliable output from this method you must make sure it is called once the frame rendering has ended, and not during the rendering process. A simple way of ensuring this is to call it from a coroutine that yields on WaitForEndOfFrame. If you call this method during the rendering process you will get unpredictable and undefined results.
IEnumerator RecordFrame()
{
yield return new WaitForEndOfFrame();
var texture = ScreenCapture.CaptureScreenshotAsTexture();
Object.Destroy(texture);
}
public void LateUpdate()
{
StartCoroutine(RecordFrame());
}
三、使用Texture2D的ReadPixels获得Texture2D(这个的协程 必须在OnGUI中调用才可以)
public static Texture2D CaptureScreen(Camera came, Rect r) {
RenderTexture rt = new RenderTexture((int)r.width, (int)r.height, 0);
came.targetTexture = rt;
came.Render();
RenderTexture.active = rt;
Texture2D screenShot = new Texture2D((int)r.width, (int)r.height, TextureFormat.RGB24, false);
screenShot.ReadPixels(r, 0, 0);
screenShot.Apply();
came.targetTexture = null;
RenderTexture.active = null;
Destroy(rt);
byte[] bytes = screenShot.EncodeToPNG();
string filename = Application.streamingAssetsPath + "/aaaaaaaaScreenShot.png";
File.WriteAllBytes(filename, bytes);
return screenShot;
}
其中方案方案一、二在使用中能得到正确的图片,截取的是全屏,但是也会截取到UI。
方案三可以根据设置的Rect截取任意部分屏幕,可以根据参数came当前渲染的部分进行选择性截屏,但是在本人项目中使用时有渲染逻辑问题,即不同类型的物体在截屏后会有渲染先后的问题,其他人也遇到过这个问题,可能是因为没有在OnGUI中调用,暂时未测试,我在项目中使用的是方案二,然后再根据需要的位置进行截取和压缩图片,代码如下:
public static Texture2D ResetTexture(Texture2D orginalTexture,int resetWidth,int resetHeight) {
Texture2D orginalTextureReset = new Texture2D(orginalTexture.height, orginalTexture.height, TextureFormat.RGB24, false);
Color color;
int cutValue=420;
for (int i = 0; i < orginalTextureReset.width; i++) {
for (int j = 0; j < orginalTextureReset.height; j++) {
color = orginalTexture.GetPixel(i+ cutValue, j);
orginalTextureReset.SetPixel(i, j, color);
}
}
Texture2D newTexture = new Texture2D(resetWidth, resetHeight, TextureFormat.RGB24, false);
for (int i = 0; i < newTexture.height; i++)
{
for (int j = 0; j < newTexture.width; j++) {
color = orginalTextureReset.GetPixel((int)(i * 8.4375f), (int)(j * 8.4375f));
newTexture.SetPixel(i, j, color);
}
}
newTexture.Apply();
return newTexture;
}
上面代码的功能是将orginalTexture截取成最大居中正方形(项目为19201080,所有截取后为10801080),并压缩成128*128像素。其中数值420=(1920-1080)/2;8.4375=1080/128。项目中的截图用于一个小图标,经过测试保存成有损的jpg会比png小很多(5k之于13k),因此使用Texture2D.EncodeToJPG保存。
四、将Texture2D转换成string进行网络传输
System.Convert.ToBase64String(texture2D.EncodeToJPG())
五、将string转换成sprite显示在Image上
Texture2D texture = new Texture2D(128, 128);
texture.LoadImage(System.Convert.FromBase64String(textureString);
thumbnailImage.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);