回答編集履歴

1

RawImageからPNGデータを作る例を追記

2022/03/19 14:03

投稿

Bongo
Bongo

スコア10816

test CHANGED
@@ -2,3 +2,85 @@
2
2
  見たところ少なくとも後者の`CaptureScreenshot`案のコードには`Apply`がないように見えます。`saveText.SetPixels(colors);`の後に`saveText.Apply();`を入れてみると変化はあるでしょうか。
3
3
 
4
4
  前者の直接保存案がうまくいかなかった件については、こちらはもっと詳しくコードをご提示いただく必要がありそうです。ご参考になさった「[【Unity】シェーダーを利用して音声波形を描く - setchi’s blog](https://setchi.hatenablog.com/entry/2015/10/25/220844)」によると、`WaveformRenderer`の`texture`自体は音声データを赤色の強度で表した高さ1ピクセルのテクスチャのようですから、それを最終的な緑色の線の画像にするにはどこかで記事中のシェーダーを使ったレンダリングを行う必要があるかと思います。ご質問者さんがどのようになさっているかお示しいただければ手がかりになるかもしれません。
5
+
6
+ ## RawImageから画像データを作る例
7
+
8
+ 生成された波形データテクスチャを`RawImage`上にレンダリングして波形図にすることを前提とすると、その`RawImage`のマテリアルを使って波形データテクスチャを同様にオフスクリーンレンダリングする手があるんじゃないかと思いました。
9
+ ご参考までに、たとえば下記のようなスクリプトをプロジェクト内に入れておけば`RawImage`からPNGデータを作れるんじゃないでしょうかね?
10
+
11
+ ```C#
12
+ using UnityEngine;
13
+ using UnityEngine.UI;
14
+
15
+ public static class RawImageExtensions
16
+ {
17
+ /// <summary>
18
+ /// RawImageをキャプチャーし、PNGフォーマットにエンコードします。出力されるデータの幅、高さはRawImageのsizeDeltaを使用します。
19
+ /// </summary>
20
+ /// <param name="rawImage">キャプチャー対象のRawImage。</param>
21
+ /// <param name="ignoreAlpha">透明度を無視し、RGBのみのデータとして出力するか。</param>
22
+ /// <returns>エンコードされたPNGバイト配列。</returns>
23
+ public static byte[] EncodeToPNG(this RawImage rawImage, bool ignoreAlpha = false)
24
+ {
25
+ // 引数なしで実行した場合は、rawImageのsizeDeltaを出力テクスチャサイズとして使用する
26
+ return rawImage.EncodeToPNG(Vector2Int.FloorToInt(rawImage.rectTransform.sizeDelta), ignoreAlpha);
27
+ }
28
+
29
+ /// <summary>
30
+ /// RawImageをキャプチャーし、PNGフォーマットにエンコードします。
31
+ /// </summary>
32
+ /// <param name="rawImage">キャプチャー対象のRawImage。</param>
33
+ /// <param name="outputSize">出力されるPNGデータの幅、高さ。</param>
34
+ /// <param name="ignoreAlpha">透明度を無視し、RGBのみのデータとして出力するか。</param>
35
+ /// <returns>エンコードされたPNGバイト配列。</returns>
36
+ public static byte[] EncodeToPNG(this RawImage rawImage, Vector2Int outputSize, bool ignoreAlpha = false)
37
+ {
38
+ // 入力テクスチャを取得する
39
+ // rawImageにテクスチャがセットされていればそれを使い、なければマテリアルの
40
+ // メインテクスチャを使い、それもなければ白色テクスチャを使う
41
+ var sourceTexture = rawImage.mainTexture;
42
+
43
+ // マテリアルを取得する
44
+ var material = rawImage.material;
45
+
46
+ // 出力サイズは最低でも1ピクセル四方とする
47
+ outputSize = Vector2Int.Max(Vector2Int.one, outputSize);
48
+
49
+ // PNGデータ生成用のテクスチャを作成する
50
+ // ignoreAlphaがtrueの場合はフォーマットをRGB24とし、アルファを捨てるようにする
51
+ var resultTexture = new Texture2D(
52
+ outputSize.x,
53
+ outputSize.y,
54
+ ignoreAlpha ? TextureFormat.RGB24 : TextureFormat.RGBA32,
55
+ false);
56
+
57
+ // レンダリング用のテクスチャを生成する
58
+ var resultRenderTexture = RenderTexture.GetTemporary(outputSize.x, outputSize.y, 0);
59
+
60
+ // 後でアクティブテクスチャを原状復帰するため、現在のアクティブテクスチャを覚えておく
61
+ var activeTexture = RenderTexture.active;
62
+
63
+ // resultRenderTexture上にmaterialを使ってsourceTextureをレンダリングする
64
+ Graphics.Blit(sourceTexture, resultRenderTexture, material);
65
+
66
+ // レンダリング結果をresultTextureに読み取る
67
+ RenderTexture.active = resultRenderTexture;
68
+ resultTexture.ReadPixels(new Rect(Vector2.zero, outputSize), 0, 0);
69
+
70
+ // アクティブテクスチャを原状復帰する
71
+ RenderTexture.active = activeTexture;
72
+
73
+ // もうresultRenderTextureは不要なので解放する
74
+ RenderTexture.ReleaseTemporary(resultRenderTexture);
75
+
76
+ // PNGデータを取得する
77
+ var result = resultTexture.EncodeToPNG();
78
+
79
+ // もうresultTextureは不要なので破壊する
80
+ Object.Destroy(resultTexture);
81
+
82
+ // PNGデータを返す
83
+ return result;
84
+ }
85
+ }
86
+ ```