初めて質問させていただきます。
1. 環境
Windows 10
Unity 2020.3.29f1
2. 実現したいこと
Texture2Dを任意のサイズでトリミングする関数を作成したいです。
具体的には次のような関数です。
C#
1Texture2D Trim(Texture2D originalTexture, int x, int y, int width, int height) 2{ 3 Texture2D trimmedTexture = new Texture2D(width, height); 4 Color[] pixels = originalTexture.GetPixels(x, y, width, height); 5 trimmedTexture.SetPixels(pixels); 6 trimmedTexture.Apply(); 7 8 return trimmedTexture; 9}
originalTextureはスクリプト中で動的に生成したものを利用したいです。
(具体的には、uWindowCaptureを利用して得られた、ウィンドウのキャプチャ画像(UwcWindow.texture)です。)
3. 発生している問題
上の関数を実行すると、出力されたTextureの全てのピクセルの色が灰色でした。
次のように作成したTextureと同様の見た目です。
C#
1Texture2D texture = new Texture2D(width, height);
ただし、エラーは出ていません。
正しい色が出力されるようにしたいです。
4. 試したこと
Read/Write Enabledの確認
関数内でoriginalTexture.isReadableを確認したところ、trueでした。
C#
1Texture2D Trim(Texture2D originalTexture, int x, int y, int width, int height) 2{ 3 Debug.Log(originalTexture.isReadable); 4 // true 5 6 // 略 7}
GetPixels()によって取得したColor[]の確認
関数内でpixelsの一部をColor32にキャストして確認したところ、全てRGBA(205, 205, 205, 205)でした。
C#
1Texture2D Trim(Texture2D originalTexture, int x, int y, int width, int height) 2{ 3 for (int i = 0; i < 10; i++) 4 { 5 Debug.Log(((Color32)pixels[i]).ToString()); 6 // RGBA(205, 205, 205, 205) 7 } 8 9 // 略 10}
GetPixel()によるColorの取得
1ピクセルの色を取得するTexture2D.GetPixel()を試したところ、同様にRGBA(205, 205, 205, 205)が取得されました。
originalTextureの確認
関数内でRawImageのtextureにoriginalTextureをセットしたところ、正しい画像が表示されました。
C#
1[SerializeField] RawImage rawImage; // インスペクターで設定 2 3Texture2D Trim(Texture2D originalTexture, int x, int y, int width, int height) 4{ 5 rawImage.texture = originalTexture; 6 // GameビューのRawImageに正しい画像(灰色ではない)が表示される 7 8 // 略 9}
Graphics.CopyTexture()を利用した実装
Graphics.CopyTexture()を利用すると、実現したい関数を次のように実装することができると思います。
C#
1Texture2D Trim(Texture2D originalTexture, int x, int y, int width, int height) 2{ 3 Texture2D trimmedTexture = new Texture2D(width, height); 4 Graphics.CopyTexture(originalTexture, 0, 0, x, y, width, height, trimmedTexture, 0, 0, 0, 0); 5 trimmedTexture.Apply(); 6 7 return trimmedTexture; 8}
この場合も、同様の問題が発生しました。
5. 一応の解決方法
こちらの記事に次のような関数が掲載されています。
本来はスクリプトからRead/Write Enabledをtrueにすることを目的とした関数です。
C#
1Texture2D createReadabeTexture2D(Texture2D texture2d) 2{ 3 RenderTexture renderTexture = RenderTexture.GetTemporary( 4 texture2d.width, 5 texture2d.height, 6 0, 7 RenderTextureFormat.Default, 8 RenderTextureReadWrite.Linear); 9 10 Graphics.Blit(texture2d, renderTexture); 11 RenderTexture previous = RenderTexture.active; 12 RenderTexture.active = renderTexture; 13 Texture2D readableTextur2D = new Texture2D(texture2d.width, texture2d.height); 14 readableTextur2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); 15 readableTextur2D.Apply(); 16 RenderTexture.active = previous; 17 RenderTexture.ReleaseTemporary(renderTexture); 18 return readableTextur2D; 19}
この関数を用いて、実現したい関数を次のように書き換えたところ、(理由はわかりませんが)解決しました。
C#
1Texture2D Trim(Texture2D originalTexture, int x, int y, int width, int height) 2{ 3 Texture2D newOriginalTexture = createReadabeTexture2D(originalTexture); // 追加 4 5 Texture2D trimmedTexture = new Texture2D(width, height); 6 Color[] pixels = newOriginalTexture.GetPixels(x, y, width, height); // 変更 7 trimmedTexture.SetPixels(pixels); 8 trimmedTexture.Apply(); 9 10 return trimmedTexture; 11}
また、同様にGraphics.CopyTexture()を利用して実装した場合も、問題ありませんでした。
しかし、この関数を用いた処理は重いため、可能ならば別の方法で解決したいです。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/02/28 09:50
2022/03/09 06:34