[Unity] 截圖、縮放、Bytes轉換

最近寫到了一個存檔系統,而存檔系統的預覽圖需要當前畫面的截圖,
在實作這個功能時考慮到了以下幾點:

  1. 螢幕截圖的圖像尺寸會很大,預覽圖並不需要這麼大張的圖檔造成記憶體空間的浪費,所以想要對截圖影像作尺寸的縮放調整。
  2. 因為存檔資料的範圍都集中在一個 Class 集中管理,並不想額外儲存圖像檔,可以的話希望能轉成別的格式跟著這個 Class一併轉成 Json 檔。

最後找到了解決方案,順手在此紀錄一下。

byte[] screenshotData;


// 儲存紀錄,在此執行螢幕擷取 
protected IEnumerator SaveGameData()
{
    // 在當前禎的結尾進行截圖
    yield return new WaitForEndOfFrame();

    // 螢幕截圖的實作,並且指派到 tex 變數 (Texture2D)
    var tex = new Texture2D(Screen.width, Screen.height);
    tex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);

    // 縮放尺寸
    tex = ScaleTexture(tex, 192, 108);
    tex.Apply();

    screenshotData = tex.EncodeToPNG());
}



// 代入圖像並且指定縮放的尺寸
Texture2D ScaleTexture(Texture2D source, int targetWidth, int targetHeight)
{
    // 依據代入的尺寸實例化一個 Texture2D 物件
    var result = new Texture2D(targetWidth, targetHeight, source.format, false);

    // 圖像尺寸縮放
    for(int i = 0; i < result.height; ++i)
    {
        for(int j = 0; j < result.width; ++j)
        {
            var col = source.GetPixelBilinear(
                (float)j / result.width,
                (float)i / result.height
            );
            result.SetPixel(j, i, col);
        }
    }
    result.Apply();

    return result;
}


// 將儲存的 byte[] 轉換為圖像
Texture2D GetTextureWithBytes()
{
    var tex = new Texture2D(192, 108);
    tex.LoadImage(screenshotData);
    return tex;
}


程式碼其實還可以寫得再簡潔一點,
不過考量到功能的泛用性還是決定個別封裝起來。


[效果展示]



留言

熱門文章