回答編集履歴

2

実サイズを考慮するオプションを追加、字数削減のため旧コードを削除

2020/05/13 08:30

投稿

Bongo
Bongo

スコア10811

test CHANGED
@@ -46,6 +46,196 @@
46
46
 
47
47
  ```ShaderLab
48
48
 
49
+ // 字数節約のため削除しました...削除前のコードは編集履歴をご参照ください
50
+
51
+ ```
52
+
53
+
54
+
55
+ ご質問者さんのスクリプトを下記のように改変して実行したところ...
56
+
57
+
58
+
59
+ ```C#
60
+
61
+ using System.IO;
62
+
63
+ using UnityEditor;
64
+
65
+ using UnityEngine;
66
+
67
+
68
+
69
+ public static class TextureResizer
70
+
71
+ {
72
+
73
+ private static Material overSamplingMaterial;
74
+
75
+
76
+
77
+ [MenuItem("Utility/Resize Selected Texture to 200 x 200")]
78
+
79
+ public static void ResizeTextureTo200x200()
80
+
81
+ {
82
+
83
+ const int newWidth = 200;
84
+
85
+ const int newHeight = 200;
86
+
87
+ const int loopCount = 16;
88
+
89
+ var targetTexture = Selection.activeObject as Texture2D;
90
+
91
+ if (targetTexture == null)
92
+
93
+ {
94
+
95
+ return;
96
+
97
+ }
98
+
99
+
100
+
101
+ var targetPath = AssetDatabase.GetAssetPath(targetTexture);
102
+
103
+ if (string.IsNullOrEmpty(targetPath))
104
+
105
+ {
106
+
107
+ return;
108
+
109
+ }
110
+
111
+
112
+
113
+ var targetDirectory = Path.GetDirectoryName(targetPath);
114
+
115
+ var targetName = Path.GetFileNameWithoutExtension(targetPath);
116
+
117
+ var targetExtension = Path.GetExtension(targetPath);
118
+
119
+ var newName = $"{targetName}({newWidth}x{newHeight})";
120
+
121
+ var newPath = $"{targetDirectory}{Path.DirectorySeparatorChar}{newName}{targetExtension}";
122
+
123
+ var newTexture = GetResized(targetTexture, newWidth, newHeight, loopCount);
124
+
125
+ File.WriteAllBytes(newPath, newTexture.EncodeToPNG());
126
+
127
+ AssetDatabase.ImportAsset(newPath);
128
+
129
+ }
130
+
131
+
132
+
133
+ private static Texture2D GetResized(Texture2D texture, int width, int height, int loopCount)
134
+
135
+ {
136
+
137
+ // オーバーサンプリング用マテリアルを作成する
138
+
139
+ if (overSamplingMaterial == null)
140
+
141
+ {
142
+
143
+ overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
144
+
145
+ }
146
+
147
+
148
+
149
+ // まず元と同じサイズのRenderTextureに書き込む
150
+
151
+ var sourceRT = RenderTexture.GetTemporary(texture.width, texture.height);
152
+
153
+ Graphics.Blit(texture, sourceRT);
154
+
155
+
156
+
157
+ // filterModeをPointにしておき、サンプリング時に注目点以外の色が混じらないようにしておく
158
+
159
+ sourceRT.filterMode = FilterMode.Point;
160
+
161
+
162
+
163
+ // リサイズ後のサイズを持つRenderTextureを作成して、オーバーサンプリングマテリアルを使って書き込む
164
+
165
+ var rt = RenderTexture.GetTemporary(width, height);
166
+
167
+ overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
168
+
169
+ Graphics.Blit(sourceRT, rt, overSamplingMaterial);
170
+
171
+
172
+
173
+ // リサイズ後のサイズを持つTexture2Dを作成してRenderTextureから書き込む
174
+
175
+ var preRT = RenderTexture.active;
176
+
177
+ RenderTexture.active = rt;
178
+
179
+ var ret = new Texture2D(width, height);
180
+
181
+ ret.ReadPixels(new Rect(0, 0, width, height), 0, 0);
182
+
183
+ ret.Apply();
184
+
185
+ RenderTexture.active = preRT;
186
+
187
+ RenderTexture.ReleaseTemporary(rt);
188
+
189
+ RenderTexture.ReleaseTemporary(sourceRT);
190
+
191
+ return ret;
192
+
193
+ }
194
+
195
+ }
196
+
197
+ ```
198
+
199
+
200
+
201
+ `loopCount`が1だと(これは実質的にニアレストネイバー法と同等のはずです)...
202
+
203
+
204
+
205
+ ![図5](eaf1956e5781b0d3c641c38c6756b0ec.png)
206
+
207
+
208
+
209
+ `loopCount`が4だと(1ピクセルにつき16点サンプリング)...
210
+
211
+
212
+
213
+ ![図6](65ef555c583c53d871a8ce3f1aaf1453.png)
214
+
215
+
216
+
217
+ `loopCount`が16だと(1ピクセルにつき256点サンプリング)...
218
+
219
+
220
+
221
+ ![図7](830198f126de168c40362776a29031ee.png)
222
+
223
+
224
+
225
+ となりました。だいぶ精密さが向上したんじゃないかと思いますが、いかがでしょうか?
226
+
227
+
228
+
229
+ **正方形トリミングについて**
230
+
231
+
232
+
233
+ まずシェーダーコードは下記のように変更して、UV座標を操作することで画像切り出し範囲を調整できるようにしておきます。
234
+
235
+
236
+
237
+ ```ShaderLab
238
+
49
239
  Shader "Hidden/OverSampling"
50
240
 
51
241
  {
@@ -106,6 +296,14 @@
106
296
 
107
297
 
108
298
 
299
+ sampler2D _MainTex;
300
+
301
+ float4 _TilingAndOffset;
302
+
303
+ int _LoopCount;
304
+
305
+
306
+
109
307
  v2f vert(appdata v)
110
308
 
111
309
  {
@@ -114,7 +312,7 @@
114
312
 
115
313
  o.vertex = UnityObjectToClipPos(v.vertex);
116
314
 
117
- o.uv = v.uv;
315
+ o.uv = (v.uv * _TilingAndOffset.xy) + _TilingAndOffset.zw;
118
316
 
119
317
  return o;
120
318
 
@@ -122,12 +320,6 @@
122
320
 
123
321
 
124
322
 
125
- sampler2D _MainTex;
126
-
127
- int _LoopCount;
128
-
129
-
130
-
131
323
  float4 frag (v2f i) : SV_Target
132
324
 
133
325
  {
@@ -170,21 +362,25 @@
170
362
 
171
363
 
172
364
 
173
- ご質問者さんのスクリプト下記のように改変て実行したところ...
365
+ そして制御用のスクリプト下記のようにしした
366
+
367
+ ご追記のスクリーンショットを拝見しますに、どうやらImageを使って縮小後のテクスチャを表示している様子ですね。表示用のスプライトはどのように用意していますでしょうか?私の場合はさしあたり縮小後のテクスチャを使ったスプライトを新規作成し、それを`Image`コンポーネントにセットしてやることにしました。
368
+
369
+ スクリプトはサイズ200×200のImageオブジェクトにアタッチして使うことを想定しており、`Start`内で元テクスチャをロード・縮小テクスチャを生成・スプライトを作成して`Image`にセット...の処理を行っています。
174
370
 
175
371
 
176
372
 
177
373
  ```C#
178
374
 
179
- using System.IO;
180
-
181
- using UnityEditor;
182
-
183
375
  using UnityEngine;
184
376
 
185
-
377
+ using UnityEngine.UI;
378
+
379
+
380
+
186
-
381
+ [RequireComponent(typeof(Image))]
382
+
187
- public static class TextureResizer
383
+ public class ResizedImageLoader : MonoBehaviour
188
384
 
189
385
  {
190
386
 
@@ -192,103 +388,251 @@
192
388
 
193
389
 
194
390
 
195
- [MenuItem("Utility/Resize Selected Texture to 200 x 200")]
196
-
197
- public static void ResizeTextureTo200x200()
391
+ [SerializeField] private bool useActualSize;
392
+
393
+
394
+
395
+ private void Start()
198
396
 
199
397
  {
200
398
 
399
+ var texture2D = Resources.Load<Texture2D>("motogp");
400
+
401
+
402
+
403
+ // 目標サイズは200x200決め打ちではなく、Imageのサイズを見て決めることにする
404
+
201
- const int newWidth = 200;
405
+ var image = this.GetComponent<Image>();
202
-
203
- const int newHeight = 200;
406
+
204
-
205
- const int loopCount = 16;
206
-
207
- var targetTexture = Selection.activeObject as Texture2D;
407
+ var rectTransform = this.transform as RectTransform;
408
+
208
-
409
+ var sizeDelta = rectTransform.sizeDelta;
410
+
411
+ var toWidth = Mathf.RoundToInt(sizeDelta.x);
412
+
413
+ var toHeight = Mathf.RoundToInt(sizeDelta.y);
414
+
415
+
416
+
417
+ // インスペクターの「Use Actual Size」がオンの場合
418
+
419
+ // 目標サイズを最終的な表示サイズに合わせて調整する
420
+
209
- if (targetTexture == null)
421
+ if (this.useActualSize)
210
422
 
211
423
  {
212
424
 
213
- return;
425
+ var canvas = image.canvas;
426
+
427
+ var canvasCamera = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera;
428
+
429
+ var corners = new Vector3[4];
430
+
431
+ rectTransform.GetWorldCorners(corners);
432
+
433
+ var bottomLeft = RectTransformUtility.WorldToScreenPoint(canvasCamera, corners[0]);
434
+
435
+ var topRight = RectTransformUtility.WorldToScreenPoint(canvasCamera, corners[2]);
436
+
437
+ var actualSize = topRight - bottomLeft;
438
+
439
+ toWidth = Mathf.RoundToInt(Mathf.Abs(actualSize.x));
440
+
441
+ toHeight = Mathf.RoundToInt(Mathf.Abs(actualSize.y));
214
442
 
215
443
  }
216
444
 
217
445
 
218
446
 
447
+ // 元のテクスチャから切り出すべき領域を求める
448
+
449
+ // テクスチャの中心からなるべく大きな矩形を切り出したいので
450
+
451
+ // まずテクスチャの高さに縦横比を掛けて希望切り出し幅を求める
452
+
453
+ // テクスチャの幅が希望切り出し幅よりも小さい場合、切り出し幅は
454
+
455
+ // テクスチャ幅とし、代わりに切り出し高さを切り詰める
456
+
457
+ // 起点のズレは余白の大きさの半分ということになる
458
+
459
+ var toAspect = (float)toWidth / toHeight;
460
+
461
+ var width = texture2D.width;
462
+
463
+ var height = texture2D.height;
464
+
465
+ var expectedWidth = Mathf.RoundToInt(height * toAspect);
466
+
219
- var targetPath = AssetDatabase.GetAssetPath(targetTexture);
467
+ var fromWidth = Mathf.Min(width, expectedWidth);
468
+
220
-
469
+ var fromHeight = expectedWidth > width ? Mathf.RoundToInt(width / toAspect) : height;
470
+
471
+ var offsetX = (width - fromWidth) / 2;
472
+
473
+ var offsetY = (height - fromHeight) / 2;
474
+
475
+
476
+
477
+ // 確認のため、リサイズ前とリサイズ後のサイズをコンソールに表示してみる
478
+
479
+ Debug.LogFormat("({0}, {1}) -> [({2}, {3}), ({4}, {5})] -> ({6}, {7})",
480
+
481
+ width, height,
482
+
483
+ offsetX, offsetY, fromWidth, fromHeight,
484
+
485
+ toWidth, toHeight);
486
+
487
+
488
+
489
+ // 切り出された領域をリサイズして最終的なテクスチャとする
490
+
491
+ // ちなみに、ご質問者さんが作成された方のGetResizedも残してありますので、
492
+
493
+ // 引数を元テクスチャと目標サイズだけに省略するとそちらが使われます
494
+
495
+ // そちらに切り替えてみると、トリミング処理の有無による違いやぼけ具合の
496
+
497
+ // 比較ができるかと思います
498
+
499
+ var resizedTexture = GetResized(texture2D, offsetX, offsetY, fromWidth, fromHeight, toWidth, toHeight);
500
+
501
+ //var resizedTexture = GetResized(texture2D, 200, 200);
502
+
503
+
504
+
505
+ // 最終的に表示される位置・サイズによっては、小数点以下のズレのため
506
+
507
+ // ぼやけやImage外周部に反対側の辺の色が乗る現象が起こる可能性がある
508
+
509
+ // そこで、それらを回避するようにテクスチャの設定を変更する
510
+
511
+ resizedTexture.filterMode = FilterMode.Point;
512
+
513
+ resizedTexture.wrapMode = TextureWrapMode.Clamp;
514
+
515
+
516
+
517
+ // リサイズ後のテクスチャをもとにスプライトを作成し、Imageにセット
518
+
519
+ var sprite = Sprite.Create(
520
+
521
+ resizedTexture,
522
+
523
+ new Rect(0, 0, resizedTexture.width, resizedTexture.height),
524
+
525
+ new Vector2(0.5f, 0.5f));
526
+
527
+ image.sprite = sprite;
528
+
529
+ }
530
+
531
+
532
+
533
+ // 元のテクスチャから(fromX, fromY)を起点とする幅fromWidth、高さfromHeightの領域を
534
+
535
+ // 切り出し、それを幅toWidth、高さtoHeightにリサイズしたテクスチャを生成する
536
+
537
+ private static Texture2D GetResized(
538
+
539
+ Texture2D texture,
540
+
541
+ int fromX, int fromY, int fromWidth, int fromHeight,
542
+
543
+ int toWidth, int toHeight,
544
+
545
+ int loopCount = 16,
546
+
547
+ bool generateMipmaps = false)
548
+
549
+ {
550
+
221
- if (string.IsNullOrEmpty(targetPath))
551
+ if (overSamplingMaterial == null)
222
552
 
223
553
  {
224
554
 
225
- return;
555
+ overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
226
556
 
227
557
  }
228
558
 
229
559
 
230
560
 
561
+ // まずは以前同様に元テクスチャをRenderTextureに写し取り、FilterModeをPointにしておく
562
+
231
- var targetDirectory = Path.GetDirectoryName(targetPath);
563
+ var preRT = RenderTexture.active;
232
-
233
- var targetName = Path.GetFileNameWithoutExtension(targetPath);
564
+
234
-
235
- var targetExtension = Path.GetExtension(targetPath);
565
+ var sourceWidth = texture.width;
566
+
236
-
567
+ var sourceHeight = texture.height;
568
+
237
- var newName = $"{targetName}({newWidth}x{newHeight})";
569
+ var sourceRT = RenderTexture.GetTemporary(sourceWidth, sourceHeight);
570
+
238
-
571
+ Graphics.Blit(texture, sourceRT);
572
+
573
+ sourceRT.filterMode = FilterMode.Point;
574
+
575
+
576
+
577
+ // マテリアルの設定を行う
578
+
579
+ // 元のテクスチャから起点(fromX, fromY)、サイズ(fromWidth, fromHeight)の部分を
580
+
581
+ // 切り出すということは、UV座標のタイリング・オフセットは下記のようになる
582
+
583
+ overSamplingMaterial.SetVector(
584
+
585
+ "_TilingAndOffset",
586
+
587
+ new Vector4(
588
+
589
+ (float)fromWidth / sourceWidth,
590
+
591
+ (float)fromHeight / sourceHeight,
592
+
593
+ (float)fromX / sourceWidth,
594
+
595
+ (float)fromY / sourceHeight));
596
+
239
- var newPath = $"{targetDirectory}{Path.DirectorySeparatorChar}{newName}{targetExtension}";
597
+ overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
598
+
599
+
600
+
240
-
601
+ // あとは以前と同様にリサイズし、結果を返す
602
+
241
- var newTexture = GetResized(targetTexture, newWidth, newHeight, loopCount);
603
+ var rt = RenderTexture.GetTemporary(toWidth, toHeight);
604
+
242
-
605
+ Graphics.Blit(sourceRT, rt, overSamplingMaterial);
606
+
607
+ RenderTexture.active = rt;
608
+
609
+ var ret = new Texture2D(toWidth, toHeight, TextureFormat.ARGB32, generateMipmaps);
610
+
243
- File.WriteAllBytes(newPath, newTexture.EncodeToPNG());
611
+ ret.ReadPixels(new Rect(0, 0, toWidth, toHeight), 0, 0);
612
+
244
-
613
+ ret.Apply();
614
+
615
+ RenderTexture.active = preRT;
616
+
617
+ RenderTexture.ReleaseTemporary(rt);
618
+
245
- AssetDatabase.ImportAsset(newPath);
619
+ RenderTexture.ReleaseTemporary(sourceRT);
620
+
621
+ return ret;
246
622
 
247
623
  }
248
624
 
249
625
 
250
626
 
627
+ // ご質問者さんの方法によるGetResized
628
+
251
- private static Texture2D GetResized(Texture2D texture, int width, int height, int loopCount)
629
+ private static Texture2D GetResized(Texture2D texture, int width, int height)
252
630
 
253
631
  {
254
632
 
255
- // オーバーサンプリング用マテリアルを作成する
256
-
257
- if (overSamplingMaterial == null)
258
-
259
- {
260
-
261
- overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
262
-
263
- }
264
-
265
-
266
-
267
- // まず元と同じサイズのRenderTextureに書き込む
268
-
269
- var sourceRT = RenderTexture.GetTemporary(texture.width, texture.height);
270
-
271
- Graphics.Blit(texture, sourceRT);
272
-
273
-
274
-
275
- // filterModeをPointにしておき、サンプリング時に注目点以外の色が混じらないようにしておく
276
-
277
- sourceRT.filterMode = FilterMode.Point;
278
-
279
-
280
-
281
- // リサイズ後のサイズを持つRenderTextureを作成して、オーバーサンプリングマテリアルを使って書き込む
282
-
283
633
  var rt = RenderTexture.GetTemporary(width, height);
284
634
 
285
- overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
286
-
287
- Graphics.Blit(sourceRT, rt, overSamplingMaterial);
635
+ Graphics.Blit(texture, rt);
288
-
289
-
290
-
291
- // リサイズ後のサイズを持つTexture2Dを作成してRenderTextureから書き込む
292
636
 
293
637
  var preRT = RenderTexture.active;
294
638
 
@@ -304,8 +648,6 @@
304
648
 
305
649
  RenderTexture.ReleaseTemporary(rt);
306
650
 
307
- RenderTexture.ReleaseTemporary(sourceRT);
308
-
309
651
  return ret;
310
652
 
311
653
  }
@@ -316,378 +658,6 @@
316
658
 
317
659
 
318
660
 
319
- `loopCount`が1だと(これは実質的にニアレストネイバー法と同等のはずです)...
320
-
321
-
322
-
323
- ![図5](eaf1956e5781b0d3c641c38c6756b0ec.png)
324
-
325
-
326
-
327
- `loopCount`が4だと(1ピクセルにつき16点サンプリング)...
328
-
329
-
330
-
331
- ![図6](65ef555c583c53d871a8ce3f1aaf1453.png)
332
-
333
-
334
-
335
- `loopCount`が16だと(1ピクセルにつき256点サンプリング)...
336
-
337
-
338
-
339
- ![図7](830198f126de168c40362776a29031ee.png)
340
-
341
-
342
-
343
- となりました。だいぶ精密さが向上したんじゃないかと思いますが、いかがでしょうか?
344
-
345
-
346
-
347
- **正方形トリミングについて**
348
-
349
-
350
-
351
- まずシェーダーコードは下記のように変更して、UV座標を操作することで画像切り出し範囲を調整できるようにしておきます。
352
-
353
-
354
-
355
- ```ShaderLab
356
-
357
- Shader "Hidden/OverSampling"
358
-
359
- {
360
-
361
- Properties
362
-
363
- {
364
-
365
- _MainTex ("Texture", 2D) = "white" {}
366
-
367
- }
368
-
369
- SubShader
370
-
371
- {
372
-
373
- Cull Off ZWrite Off ZTest Always
374
-
375
-
376
-
377
- Pass
378
-
379
- {
380
-
381
- CGPROGRAM
382
-
383
- #pragma vertex vert
384
-
385
- #pragma fragment frag
386
-
387
-
388
-
389
- #include "UnityCG.cginc"
390
-
391
-
392
-
393
- struct appdata
394
-
395
- {
396
-
397
- float4 vertex : POSITION;
398
-
399
- float2 uv : TEXCOORD0;
400
-
401
- };
402
-
403
-
404
-
405
- struct v2f
406
-
407
- {
408
-
409
- float2 uv : TEXCOORD0;
410
-
411
- float4 vertex : SV_POSITION;
412
-
413
- };
414
-
415
-
416
-
417
- sampler2D _MainTex;
418
-
419
- float4 _TilingAndOffset;
420
-
421
- int _LoopCount;
422
-
423
-
424
-
425
- v2f vert(appdata v)
426
-
427
- {
428
-
429
- v2f o;
430
-
431
- o.vertex = UnityObjectToClipPos(v.vertex);
432
-
433
- o.uv = (v.uv * _TilingAndOffset.xy) + _TilingAndOffset.zw;
434
-
435
- return o;
436
-
437
- }
438
-
439
-
440
-
441
- float4 frag (v2f i) : SV_Target
442
-
443
- {
444
-
445
- float2 texelSize = fwidth(i.uv);
446
-
447
- float2 deltaUV = texelSize / _LoopCount;
448
-
449
- float2 uv0 = i.uv + ((deltaUV - texelSize) * 0.5);
450
-
451
- float4 col = 0.0;
452
-
453
- for (int j = 0; j < _LoopCount; j++)
454
-
455
- {
456
-
457
- for (int i = 0; i < _LoopCount; i++)
458
-
459
- {
460
-
461
- col += tex2D(_MainTex, uv0 + (float2(i, j) * deltaUV));
462
-
463
- }
464
-
465
- }
466
-
467
- return col / (_LoopCount * _LoopCount);
468
-
469
- }
470
-
471
- ENDCG
472
-
473
- }
474
-
475
- }
476
-
477
- }
478
-
479
- ```
480
-
481
-
482
-
483
- そして制御用のスクリプトは下記のようにしました。
484
-
485
- ご追記のスクリーンショットを拝見しますに、どうやらImageを使って縮小後のテクスチャを表示している様子ですね。表示用のスプライトはどのように用意していますでしょうか?私の場合はさしあたり縮小後のテクスチャを使ったスプライトを新規作成し、それを`Image`コンポーネントにセットしてやることにしました。
486
-
487
- スクリプトはサイズ200×200のImageオブジェクトにアタッチして使うことを想定しており、`Start`内で元テクスチャをロード・縮小テクスチャを生成・スプライトを作成して`Image`にセット...の処理を行っています。
488
-
489
-
490
-
491
- ```C#
492
-
493
- using UnityEngine;
494
-
495
- using UnityEngine.UI;
496
-
497
-
498
-
499
- [RequireComponent(typeof(Image))]
500
-
501
- public class ResizedImageLoader : MonoBehaviour
502
-
503
- {
504
-
505
- private static Material overSamplingMaterial;
506
-
507
-
508
-
509
- private void Start()
510
-
511
- {
512
-
513
- var texture2D = Resources.Load<Texture2D>("motogp");
514
-
515
-
516
-
517
- // まず元のテクスチャから切り出すべき領域を求める
518
-
519
- // テクスチャの中心からなるべく大きな正方形を切り出したいので
520
-
521
- // 正方形の一辺の長さは幅と高さのうち小さい方であり、起点のズレは
522
-
523
- // 余白の大きさの半分ということになる
524
-
525
- var width = texture2D.width;
526
-
527
- var height = texture2D.height;
528
-
529
- var size = width > height ? height : width;
530
-
531
- var offsetX = (width - size) / 2;
532
-
533
- var offsetY = (height - size) / 2;
534
-
535
-
536
-
537
- // 切り出された領域を200x200に縮小して最終的なテクスチャとする
538
-
539
- // ちなみに、ご質問者さんが作成された方のGetResizedも残してありますので、
540
-
541
- // 引数を元テクスチャと縮小後サイズだけに省略するとそちらが使われます
542
-
543
- // そちらに切り替えてみると、トリミング処理の有無による違いやぼけ具合の
544
-
545
- // 比較ができるかと思います
546
-
547
- var resizedTexture = GetResized(texture2D, offsetX, offsetY, size, size, 200, 200);
548
-
549
- //var resizedTexture = GetResized(texture2D, 200, 200);
550
-
551
-
552
-
553
- // リサイズ後のテクスチャをもとにスプライトを作成し、Imageにセット
554
-
555
- var sprite = Sprite.Create(
556
-
557
- resizedTexture,
558
-
559
- new Rect(0, 0, resizedTexture.width, resizedTexture.height),
560
-
561
- new Vector2(0.5f, 0.5f));
562
-
563
- this.GetComponent<Image>().sprite = sprite;
564
-
565
- }
566
-
567
-
568
-
569
- // 元のテクスチャから(fromX, fromY)を起点とする幅fromWidth、高さfromHeightの領域を
570
-
571
- // 切り出し、それを幅toWidth、高さtoHeightにリサイズしたテクスチャを生成する
572
-
573
- private static Texture2D GetResized(
574
-
575
- Texture2D texture,
576
-
577
- int fromX, int fromY, int fromWidth, int fromHeight,
578
-
579
- int toWidth, int toHeight,
580
-
581
- int loopCount = 16)
582
-
583
- {
584
-
585
- if (overSamplingMaterial == null)
586
-
587
- {
588
-
589
- overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
590
-
591
- }
592
-
593
-
594
-
595
- // まずは以前同様に元テクスチャをRenderTextureに写し取り、FilterModeをPointにしておく
596
-
597
- var preRT = RenderTexture.active;
598
-
599
- var sourceWidth = texture.width;
600
-
601
- var sourceHeight = texture.height;
602
-
603
- var sourceRT = RenderTexture.GetTemporary(sourceWidth, sourceHeight);
604
-
605
- Graphics.Blit(texture, sourceRT);
606
-
607
- sourceRT.filterMode = FilterMode.Point;
608
-
609
-
610
-
611
- // マテリアルの設定を行う
612
-
613
- // 元のテクスチャから起点(fromX, fromY)、サイズ(fromWidth, fromHeight)の部分を
614
-
615
- // 切り出すということは、UV座標のタイリング・オフセットは下記のようになる
616
-
617
- overSamplingMaterial.SetVector(
618
-
619
- "_TilingAndOffset",
620
-
621
- new Vector4(
622
-
623
- (float)fromWidth / sourceWidth, (float)fromHeight / sourceHeight,
624
-
625
- (float)fromX / sourceWidth, (float)fromY / sourceHeight));
626
-
627
- overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
628
-
629
-
630
-
631
- // あとは以前と同様にリサイズし、結果を返す
632
-
633
- var rt = RenderTexture.GetTemporary(toWidth, toHeight);
634
-
635
- Graphics.Blit(sourceRT, rt, overSamplingMaterial);
636
-
637
- RenderTexture.active = rt;
638
-
639
- var ret = new Texture2D(toWidth, toHeight);
640
-
641
- ret.ReadPixels(new Rect(0, 0, toWidth, toHeight), 0, 0);
642
-
643
- ret.Apply();
644
-
645
- RenderTexture.active = preRT;
646
-
647
- RenderTexture.ReleaseTemporary(rt);
648
-
649
- RenderTexture.ReleaseTemporary(sourceRT);
650
-
651
- return ret;
652
-
653
- }
654
-
655
-
656
-
657
- // ご質問者さんの方法によるGetResized
658
-
659
- private static Texture2D GetResized(Texture2D texture, int width, int height)
660
-
661
- {
662
-
663
- var rt = RenderTexture.GetTemporary(width, height);
664
-
665
- Graphics.Blit(texture, rt);
666
-
667
- var preRT = RenderTexture.active;
668
-
669
- RenderTexture.active = rt;
670
-
671
- var ret = new Texture2D(width, height);
672
-
673
- ret.ReadPixels(new Rect(0, 0, width, height), 0, 0);
674
-
675
- ret.Apply();
676
-
677
- RenderTexture.active = preRT;
678
-
679
- RenderTexture.ReleaseTemporary(rt);
680
-
681
- return ret;
682
-
683
- }
684
-
685
- }
686
-
687
- ```
688
-
689
-
690
-
691
661
  当初の方法だと、縦長の画像が正方形に縮小されることで縦に潰れてしまっていたのが...
692
662
 
693
663
 

1

正方形トリミング案を追記

2020/05/13 08:30

投稿

Bongo
Bongo

スコア10811

test CHANGED
@@ -50,119 +50,119 @@
50
50
 
51
51
  {
52
52
 
53
- Properties
54
-
55
- {
56
-
57
- _MainTex ("Texture", 2D) = "white" {}
58
-
59
- }
60
-
61
- SubShader
62
-
63
- {
64
-
65
- Cull Off ZWrite Off ZTest Always
66
-
67
-
68
-
69
- Pass
70
-
71
- {
72
-
73
- CGPROGRAM
74
-
75
- #pragma vertex vert
76
-
77
- #pragma fragment frag
78
-
79
-
80
-
81
- #include "UnityCG.cginc"
82
-
83
-
84
-
85
- struct appdata
86
-
87
- {
88
-
89
- float4 vertex : POSITION;
90
-
91
- float2 uv : TEXCOORD0;
92
-
93
- };
94
-
95
-
96
-
97
- struct v2f
98
-
99
- {
100
-
101
- float2 uv : TEXCOORD0;
102
-
103
- float4 vertex : SV_POSITION;
104
-
105
- };
106
-
107
-
108
-
109
- v2f vert(appdata v)
110
-
111
- {
112
-
113
- v2f o;
114
-
115
- o.vertex = UnityObjectToClipPos(v.vertex);
116
-
117
- o.uv = v.uv;
118
-
119
- return o;
120
-
121
- }
122
-
123
-
124
-
125
- sampler2D _MainTex;
126
-
127
- int _LoopCount;
128
-
129
-
130
-
131
- float4 frag (v2f i) : SV_Target
132
-
133
- {
134
-
135
- float2 texelSize = fwidth(i.uv);
136
-
137
- float2 deltaUV = texelSize / _LoopCount;
138
-
139
- float2 uv0 = i.uv + ((deltaUV - texelSize) * 0.5);
140
-
141
- float4 col = 0.0;
142
-
143
- for (int j = 0; j < _LoopCount; j++)
144
-
145
- {
146
-
147
- for (int i = 0; i < _LoopCount; i++)
148
-
149
- {
150
-
151
- col += tex2D(_MainTex, uv0 + (float2(i, j) * deltaUV));
152
-
153
- }
154
-
155
- }
156
-
157
- return col / (_LoopCount * _LoopCount);
158
-
159
- }
160
-
161
- ENDCG
162
-
163
- }
164
-
165
- }
53
+ Properties
54
+
55
+ {
56
+
57
+ _MainTex ("Texture", 2D) = "white" {}
58
+
59
+ }
60
+
61
+ SubShader
62
+
63
+ {
64
+
65
+ Cull Off ZWrite Off ZTest Always
66
+
67
+
68
+
69
+ Pass
70
+
71
+ {
72
+
73
+ CGPROGRAM
74
+
75
+ #pragma vertex vert
76
+
77
+ #pragma fragment frag
78
+
79
+
80
+
81
+ #include "UnityCG.cginc"
82
+
83
+
84
+
85
+ struct appdata
86
+
87
+ {
88
+
89
+ float4 vertex : POSITION;
90
+
91
+ float2 uv : TEXCOORD0;
92
+
93
+ };
94
+
95
+
96
+
97
+ struct v2f
98
+
99
+ {
100
+
101
+ float2 uv : TEXCOORD0;
102
+
103
+ float4 vertex : SV_POSITION;
104
+
105
+ };
106
+
107
+
108
+
109
+ v2f vert(appdata v)
110
+
111
+ {
112
+
113
+ v2f o;
114
+
115
+ o.vertex = UnityObjectToClipPos(v.vertex);
116
+
117
+ o.uv = v.uv;
118
+
119
+ return o;
120
+
121
+ }
122
+
123
+
124
+
125
+ sampler2D _MainTex;
126
+
127
+ int _LoopCount;
128
+
129
+
130
+
131
+ float4 frag (v2f i) : SV_Target
132
+
133
+ {
134
+
135
+ float2 texelSize = fwidth(i.uv);
136
+
137
+ float2 deltaUV = texelSize / _LoopCount;
138
+
139
+ float2 uv0 = i.uv + ((deltaUV - texelSize) * 0.5);
140
+
141
+ float4 col = 0.0;
142
+
143
+ for (int j = 0; j < _LoopCount; j++)
144
+
145
+ {
146
+
147
+ for (int i = 0; i < _LoopCount; i++)
148
+
149
+ {
150
+
151
+ col += tex2D(_MainTex, uv0 + (float2(i, j) * deltaUV));
152
+
153
+ }
154
+
155
+ }
156
+
157
+ return col / (_LoopCount * _LoopCount);
158
+
159
+ }
160
+
161
+ ENDCG
162
+
163
+ }
164
+
165
+ }
166
166
 
167
167
  }
168
168
 
@@ -188,127 +188,127 @@
188
188
 
189
189
  {
190
190
 
191
- private static Material overSamplingMaterial;
192
-
193
-
194
-
195
- [MenuItem("Utility/Resize Selected Texture to 200 x 200")]
196
-
197
- public static void ResizeTextureTo200x200()
198
-
199
- {
200
-
201
- const int newWidth = 200;
202
-
203
- const int newHeight = 200;
204
-
205
- const int loopCount = 16;
206
-
207
- var targetTexture = Selection.activeObject as Texture2D;
208
-
209
- if (targetTexture == null)
210
-
211
- {
212
-
213
- return;
214
-
215
- }
216
-
217
-
218
-
219
- var targetPath = AssetDatabase.GetAssetPath(targetTexture);
220
-
221
- if (string.IsNullOrEmpty(targetPath))
222
-
223
- {
224
-
225
- return;
226
-
227
- }
228
-
229
-
230
-
231
- var targetDirectory = Path.GetDirectoryName(targetPath);
232
-
233
- var targetName = Path.GetFileNameWithoutExtension(targetPath);
234
-
235
- var targetExtension = Path.GetExtension(targetPath);
236
-
237
- var newName = $"{targetName}({newWidth}x{newHeight})";
238
-
239
- var newPath = $"{targetDirectory}{Path.DirectorySeparatorChar}{newName}{targetExtension}";
240
-
241
- var newTexture = GetResized(targetTexture, newWidth, newHeight, loopCount);
242
-
243
- File.WriteAllBytes(newPath, newTexture.EncodeToPNG());
244
-
245
- AssetDatabase.ImportAsset(newPath);
246
-
247
- }
248
-
249
-
250
-
251
- private static Texture2D GetResized(Texture2D texture, int width, int height, int loopCount)
252
-
253
- {
254
-
255
- // オーバーサンプリング用マテリアルを作成する
256
-
257
- if (overSamplingMaterial == null)
258
-
259
- {
260
-
261
- overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
262
-
263
- }
264
-
265
-
266
-
267
- // まず元と同じサイズのRenderTextureに書き込む
268
-
269
- var sourceRT = RenderTexture.GetTemporary(texture.width, texture.height);
270
-
271
- Graphics.Blit(texture, sourceRT);
272
-
273
-
274
-
275
- // filterModeをPointにしておき、サンプリング時に注目点以外の色が混じらないようにしておく
276
-
277
- sourceRT.filterMode = FilterMode.Point;
278
-
279
-
280
-
281
- // リサイズ後のサイズを持つRenderTextureを作成して、オーバーサンプリングマテリアルを使って書き込む
282
-
283
- var rt = RenderTexture.GetTemporary(width, height);
284
-
285
- overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
286
-
287
- Graphics.Blit(sourceRT, rt, overSamplingMaterial);
288
-
289
-
290
-
291
- // リサイズ後のサイズを持つTexture2Dを作成してRenderTextureから書き込む
292
-
293
- var preRT = RenderTexture.active;
294
-
295
- RenderTexture.active = rt;
296
-
297
- var ret = new Texture2D(width, height);
298
-
299
- ret.ReadPixels(new Rect(0, 0, width, height), 0, 0);
300
-
301
- ret.Apply();
302
-
303
- RenderTexture.active = preRT;
304
-
305
- RenderTexture.ReleaseTemporary(rt);
306
-
307
- RenderTexture.ReleaseTemporary(sourceRT);
308
-
309
- return ret;
310
-
311
- }
191
+ private static Material overSamplingMaterial;
192
+
193
+
194
+
195
+ [MenuItem("Utility/Resize Selected Texture to 200 x 200")]
196
+
197
+ public static void ResizeTextureTo200x200()
198
+
199
+ {
200
+
201
+ const int newWidth = 200;
202
+
203
+ const int newHeight = 200;
204
+
205
+ const int loopCount = 16;
206
+
207
+ var targetTexture = Selection.activeObject as Texture2D;
208
+
209
+ if (targetTexture == null)
210
+
211
+ {
212
+
213
+ return;
214
+
215
+ }
216
+
217
+
218
+
219
+ var targetPath = AssetDatabase.GetAssetPath(targetTexture);
220
+
221
+ if (string.IsNullOrEmpty(targetPath))
222
+
223
+ {
224
+
225
+ return;
226
+
227
+ }
228
+
229
+
230
+
231
+ var targetDirectory = Path.GetDirectoryName(targetPath);
232
+
233
+ var targetName = Path.GetFileNameWithoutExtension(targetPath);
234
+
235
+ var targetExtension = Path.GetExtension(targetPath);
236
+
237
+ var newName = $"{targetName}({newWidth}x{newHeight})";
238
+
239
+ var newPath = $"{targetDirectory}{Path.DirectorySeparatorChar}{newName}{targetExtension}";
240
+
241
+ var newTexture = GetResized(targetTexture, newWidth, newHeight, loopCount);
242
+
243
+ File.WriteAllBytes(newPath, newTexture.EncodeToPNG());
244
+
245
+ AssetDatabase.ImportAsset(newPath);
246
+
247
+ }
248
+
249
+
250
+
251
+ private static Texture2D GetResized(Texture2D texture, int width, int height, int loopCount)
252
+
253
+ {
254
+
255
+ // オーバーサンプリング用マテリアルを作成する
256
+
257
+ if (overSamplingMaterial == null)
258
+
259
+ {
260
+
261
+ overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
262
+
263
+ }
264
+
265
+
266
+
267
+ // まず元と同じサイズのRenderTextureに書き込む
268
+
269
+ var sourceRT = RenderTexture.GetTemporary(texture.width, texture.height);
270
+
271
+ Graphics.Blit(texture, sourceRT);
272
+
273
+
274
+
275
+ // filterModeをPointにしておき、サンプリング時に注目点以外の色が混じらないようにしておく
276
+
277
+ sourceRT.filterMode = FilterMode.Point;
278
+
279
+
280
+
281
+ // リサイズ後のサイズを持つRenderTextureを作成して、オーバーサンプリングマテリアルを使って書き込む
282
+
283
+ var rt = RenderTexture.GetTemporary(width, height);
284
+
285
+ overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
286
+
287
+ Graphics.Blit(sourceRT, rt, overSamplingMaterial);
288
+
289
+
290
+
291
+ // リサイズ後のサイズを持つTexture2Dを作成してRenderTextureから書き込む
292
+
293
+ var preRT = RenderTexture.active;
294
+
295
+ RenderTexture.active = rt;
296
+
297
+ var ret = new Texture2D(width, height);
298
+
299
+ ret.ReadPixels(new Rect(0, 0, width, height), 0, 0);
300
+
301
+ ret.Apply();
302
+
303
+ RenderTexture.active = preRT;
304
+
305
+ RenderTexture.ReleaseTemporary(rt);
306
+
307
+ RenderTexture.ReleaseTemporary(sourceRT);
308
+
309
+ return ret;
310
+
311
+ }
312
312
 
313
313
  }
314
314
 
@@ -341,3 +341,363 @@
341
341
 
342
342
 
343
343
  となりました。だいぶ精密さが向上したんじゃないかと思いますが、いかがでしょうか?
344
+
345
+
346
+
347
+ **正方形トリミングについて**
348
+
349
+
350
+
351
+ まずシェーダーコードは下記のように変更して、UV座標を操作することで画像切り出し範囲を調整できるようにしておきます。
352
+
353
+
354
+
355
+ ```ShaderLab
356
+
357
+ Shader "Hidden/OverSampling"
358
+
359
+ {
360
+
361
+ Properties
362
+
363
+ {
364
+
365
+ _MainTex ("Texture", 2D) = "white" {}
366
+
367
+ }
368
+
369
+ SubShader
370
+
371
+ {
372
+
373
+ Cull Off ZWrite Off ZTest Always
374
+
375
+
376
+
377
+ Pass
378
+
379
+ {
380
+
381
+ CGPROGRAM
382
+
383
+ #pragma vertex vert
384
+
385
+ #pragma fragment frag
386
+
387
+
388
+
389
+ #include "UnityCG.cginc"
390
+
391
+
392
+
393
+ struct appdata
394
+
395
+ {
396
+
397
+ float4 vertex : POSITION;
398
+
399
+ float2 uv : TEXCOORD0;
400
+
401
+ };
402
+
403
+
404
+
405
+ struct v2f
406
+
407
+ {
408
+
409
+ float2 uv : TEXCOORD0;
410
+
411
+ float4 vertex : SV_POSITION;
412
+
413
+ };
414
+
415
+
416
+
417
+ sampler2D _MainTex;
418
+
419
+ float4 _TilingAndOffset;
420
+
421
+ int _LoopCount;
422
+
423
+
424
+
425
+ v2f vert(appdata v)
426
+
427
+ {
428
+
429
+ v2f o;
430
+
431
+ o.vertex = UnityObjectToClipPos(v.vertex);
432
+
433
+ o.uv = (v.uv * _TilingAndOffset.xy) + _TilingAndOffset.zw;
434
+
435
+ return o;
436
+
437
+ }
438
+
439
+
440
+
441
+ float4 frag (v2f i) : SV_Target
442
+
443
+ {
444
+
445
+ float2 texelSize = fwidth(i.uv);
446
+
447
+ float2 deltaUV = texelSize / _LoopCount;
448
+
449
+ float2 uv0 = i.uv + ((deltaUV - texelSize) * 0.5);
450
+
451
+ float4 col = 0.0;
452
+
453
+ for (int j = 0; j < _LoopCount; j++)
454
+
455
+ {
456
+
457
+ for (int i = 0; i < _LoopCount; i++)
458
+
459
+ {
460
+
461
+ col += tex2D(_MainTex, uv0 + (float2(i, j) * deltaUV));
462
+
463
+ }
464
+
465
+ }
466
+
467
+ return col / (_LoopCount * _LoopCount);
468
+
469
+ }
470
+
471
+ ENDCG
472
+
473
+ }
474
+
475
+ }
476
+
477
+ }
478
+
479
+ ```
480
+
481
+
482
+
483
+ そして制御用のスクリプトは下記のようにしました。
484
+
485
+ ご追記のスクリーンショットを拝見しますに、どうやらImageを使って縮小後のテクスチャを表示している様子ですね。表示用のスプライトはどのように用意していますでしょうか?私の場合はさしあたり縮小後のテクスチャを使ったスプライトを新規作成し、それを`Image`コンポーネントにセットしてやることにしました。
486
+
487
+ スクリプトはサイズ200×200のImageオブジェクトにアタッチして使うことを想定しており、`Start`内で元テクスチャをロード・縮小テクスチャを生成・スプライトを作成して`Image`にセット...の処理を行っています。
488
+
489
+
490
+
491
+ ```C#
492
+
493
+ using UnityEngine;
494
+
495
+ using UnityEngine.UI;
496
+
497
+
498
+
499
+ [RequireComponent(typeof(Image))]
500
+
501
+ public class ResizedImageLoader : MonoBehaviour
502
+
503
+ {
504
+
505
+ private static Material overSamplingMaterial;
506
+
507
+
508
+
509
+ private void Start()
510
+
511
+ {
512
+
513
+ var texture2D = Resources.Load<Texture2D>("motogp");
514
+
515
+
516
+
517
+ // まず元のテクスチャから切り出すべき領域を求める
518
+
519
+ // テクスチャの中心からなるべく大きな正方形を切り出したいので
520
+
521
+ // 正方形の一辺の長さは幅と高さのうち小さい方であり、起点のズレは
522
+
523
+ // 余白の大きさの半分ということになる
524
+
525
+ var width = texture2D.width;
526
+
527
+ var height = texture2D.height;
528
+
529
+ var size = width > height ? height : width;
530
+
531
+ var offsetX = (width - size) / 2;
532
+
533
+ var offsetY = (height - size) / 2;
534
+
535
+
536
+
537
+ // 切り出された領域を200x200に縮小して最終的なテクスチャとする
538
+
539
+ // ちなみに、ご質問者さんが作成された方のGetResizedも残してありますので、
540
+
541
+ // 引数を元テクスチャと縮小後サイズだけに省略するとそちらが使われます
542
+
543
+ // そちらに切り替えてみると、トリミング処理の有無による違いやぼけ具合の
544
+
545
+ // 比較ができるかと思います
546
+
547
+ var resizedTexture = GetResized(texture2D, offsetX, offsetY, size, size, 200, 200);
548
+
549
+ //var resizedTexture = GetResized(texture2D, 200, 200);
550
+
551
+
552
+
553
+ // リサイズ後のテクスチャをもとにスプライトを作成し、Imageにセット
554
+
555
+ var sprite = Sprite.Create(
556
+
557
+ resizedTexture,
558
+
559
+ new Rect(0, 0, resizedTexture.width, resizedTexture.height),
560
+
561
+ new Vector2(0.5f, 0.5f));
562
+
563
+ this.GetComponent<Image>().sprite = sprite;
564
+
565
+ }
566
+
567
+
568
+
569
+ // 元のテクスチャから(fromX, fromY)を起点とする幅fromWidth、高さfromHeightの領域を
570
+
571
+ // 切り出し、それを幅toWidth、高さtoHeightにリサイズしたテクスチャを生成する
572
+
573
+ private static Texture2D GetResized(
574
+
575
+ Texture2D texture,
576
+
577
+ int fromX, int fromY, int fromWidth, int fromHeight,
578
+
579
+ int toWidth, int toHeight,
580
+
581
+ int loopCount = 16)
582
+
583
+ {
584
+
585
+ if (overSamplingMaterial == null)
586
+
587
+ {
588
+
589
+ overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
590
+
591
+ }
592
+
593
+
594
+
595
+ // まずは以前同様に元テクスチャをRenderTextureに写し取り、FilterModeをPointにしておく
596
+
597
+ var preRT = RenderTexture.active;
598
+
599
+ var sourceWidth = texture.width;
600
+
601
+ var sourceHeight = texture.height;
602
+
603
+ var sourceRT = RenderTexture.GetTemporary(sourceWidth, sourceHeight);
604
+
605
+ Graphics.Blit(texture, sourceRT);
606
+
607
+ sourceRT.filterMode = FilterMode.Point;
608
+
609
+
610
+
611
+ // マテリアルの設定を行う
612
+
613
+ // 元のテクスチャから起点(fromX, fromY)、サイズ(fromWidth, fromHeight)の部分を
614
+
615
+ // 切り出すということは、UV座標のタイリング・オフセットは下記のようになる
616
+
617
+ overSamplingMaterial.SetVector(
618
+
619
+ "_TilingAndOffset",
620
+
621
+ new Vector4(
622
+
623
+ (float)fromWidth / sourceWidth, (float)fromHeight / sourceHeight,
624
+
625
+ (float)fromX / sourceWidth, (float)fromY / sourceHeight));
626
+
627
+ overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
628
+
629
+
630
+
631
+ // あとは以前と同様にリサイズし、結果を返す
632
+
633
+ var rt = RenderTexture.GetTemporary(toWidth, toHeight);
634
+
635
+ Graphics.Blit(sourceRT, rt, overSamplingMaterial);
636
+
637
+ RenderTexture.active = rt;
638
+
639
+ var ret = new Texture2D(toWidth, toHeight);
640
+
641
+ ret.ReadPixels(new Rect(0, 0, toWidth, toHeight), 0, 0);
642
+
643
+ ret.Apply();
644
+
645
+ RenderTexture.active = preRT;
646
+
647
+ RenderTexture.ReleaseTemporary(rt);
648
+
649
+ RenderTexture.ReleaseTemporary(sourceRT);
650
+
651
+ return ret;
652
+
653
+ }
654
+
655
+
656
+
657
+ // ご質問者さんの方法によるGetResized
658
+
659
+ private static Texture2D GetResized(Texture2D texture, int width, int height)
660
+
661
+ {
662
+
663
+ var rt = RenderTexture.GetTemporary(width, height);
664
+
665
+ Graphics.Blit(texture, rt);
666
+
667
+ var preRT = RenderTexture.active;
668
+
669
+ RenderTexture.active = rt;
670
+
671
+ var ret = new Texture2D(width, height);
672
+
673
+ ret.ReadPixels(new Rect(0, 0, width, height), 0, 0);
674
+
675
+ ret.Apply();
676
+
677
+ RenderTexture.active = preRT;
678
+
679
+ RenderTexture.ReleaseTemporary(rt);
680
+
681
+ return ret;
682
+
683
+ }
684
+
685
+ }
686
+
687
+ ```
688
+
689
+
690
+
691
+ 当初の方法だと、縦長の画像が正方形に縮小されることで縦に潰れてしまっていたのが...
692
+
693
+
694
+
695
+ ![図8](351996976c3d2f50999f0da22b088b1d.png)
696
+
697
+
698
+
699
+ 正方形に切り出す処理が加わることで、被写体が潰れないようになりました。
700
+
701
+
702
+
703
+ ![図9](2aa29ffc694b1eb86d5f4552e091c20a.png)