天天看點

Unity局部截圖、全屏截圖、帶UI截圖方法總結彙總

根據項目的需求,在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! 

如下所示:

Unity局部截圖、全屏截圖、帶UI截圖方法總結彙總

遇到此種錯誤,解決辦法建議使用第三種利用Camera和RenderTexture進行截圖。此種方法想截取多大區域,多大的圖檔就能截取多大的圖檔。

繼續閱讀