根據項目的需求,在unity中涉及的截圖主要有全屏截圖、局部截圖、帶UI截圖等形式。下面很具這幾種形式對在unity中截圖的方法進行總結。
一、 局部截圖
public RectTransform UIRect;
void Update () {
if (Input.GetKeyDown(KeyCode.Space))
{
string fileName = Application.dataPath + "/StreamingAssets/" + "123.png";
IEnumerator coroutine = CaptureByUI(UIRect, fileName);
StartCoroutine(coroutine);
}
}
public IEnumerator CaptureByUI(RectTransform UIRect, string mFileName)
{
//等待幀畫面渲染結束
yield return new WaitForEndOfFrame();
int width = (int)(UIRect.rect.width );
int height = (int)(UIRect.rect.height);
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
//左下角為原點(0, 0)
float leftBtmX = UIRect.transform.position.x + UIRect.rect.xMin ;
float leftBtmY = UIRect.transform.position.y + UIRect.rect.yMin ;
//從螢幕讀取像素, leftBtmX/leftBtnY 是讀取的初始位置,width、height是讀取像素的寬度和高度
tex.ReadPixels(new Rect(leftBtmX, leftBtmY, width, height), 0, 0);
//執行讀取操作
tex.Apply();
byte[] bytes = tex.EncodeToPNG();
//儲存
System.IO.File.WriteAllBytes(mFileName, bytes);
}
在Canvas下建立一個Image,截去這個Image的所在區域,按下空格即可截取Image所在的區域。
二、 全屏截圖
1. unity内置了一種非常簡單的截圖方法,截取的某一幀的畫面。
public void CaptureScreenByUnity(string fileName)
{
UnityEngine.ScreenCapture.CaptureScreenshot(fileName);
}
2. 利用局部截圖裡面的方法,設定一個覆寫全屏的UI元件,也可實作全屏截圖。
3. 利用OnPostRender方法進行截圖, OnPostRender是Camera類下的方法,是以要想執行該方法,腳本必須挂載在相機下面。截取的畫面是相機畫面,如果Canvas的RenderMode為預設的ScreenSpace-Overlay,截圖是不帶UI元素的。
//該腳本必須附加在Camera相機元件所在物體對象上OnPostRender方法才會執行
//當camera完成場景的渲染時會被激活執行
private void OnPostRender()
{
if (grab)
{
//建立一個設定好的螢幕寬度和高度
//Screen.width 和 Screen.height 為在game視窗設定的寬度和高度
Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
//Read the pixels in the Rect starting at 0,0 and ending at the screen's width and height
texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, false);
texture.Apply();
byte[] bytes = texture.EncodeToPNG();
//儲存
System.IO.File.WriteAllBytes(fileName, bytes);
grab = false;
}
}
三、帶UI截圖(利用RenderTexture截圖)
需要建立一個Canvas,RenderMode設定為ScreenSpace-Camera,把需要出現在截圖當中的元素放在該Canvas下面。然後在建立一個專門進行截圖的Camera。設定該Camera為Canvas的渲染相機RenderCamera。
public void CaptureScreenByRT(Camera camera, string fileName)
{
Rect rect = new Rect(0, 0, 1920, 1080);
// 建立一個RenderTexture對象
RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);
// 臨時設定相關相機的targetTexture為rt, 并手動渲染相關相機
camera.targetTexture = rt;
camera.Render();
// 激活這個rt, 并從中中讀取像素。
RenderTexture.active = rt;
Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
// 注:這個時候,它是從RenderTexture.active中讀取像素
screenShot.ReadPixels(rect, 0, 0);
screenShot.Apply();
// 重置相關參數,以使用camera繼續在螢幕上顯示
camera.targetTexture = null;
RenderTexture.active = null;
GameObject.Destroy(rt);
// 最後将這些紋理資料,成一個png圖檔檔案
byte[] bytes = screenShot.EncodeToPNG();
System.IO.File.WriteAllBytes(fileName, bytes);
}
最後提示,使用局部截圖和全屏截圖中的方法texture.ReadPixels方法容易出現讀取像素超出邊界的錯誤,截圖變成純灰色圖檔。錯誤資訊:[d3d11] attempting to ReadPixels outside of RenderTexture bounds!
如下所示:
遇到此種錯誤,解決辦法建議使用第三種利用Camera和RenderTexture進行截圖。此種方法想截取多大區域,多大的圖檔就能截取多大的圖檔。