理由
エディター拡張機能を介して FairyGUI アトラスの小さな画像にアクセスできるようにしたいのですが、検索したところ、自分で作成するためのインターフェイスが見つかりませんでした。
方法
サムネイル情報を取得するには、UIPackage.GetItemByURL を使用します。アトラスから小さな画像をコピーします。回転されている場合は、90 度回転してください。
アトラス内の小さな画像は回転している可能性があります。NTexture.rotated にアクセスすることで、アトラス内で回転されているかどうかを確認できます。
アトラス内の小さな画像の開始位置を取得します
X オフセット座標を直接 uvRect.min.x *nativeTexture.width にすることで、実際の X オフセット
Y 座標を取得でき、これは uvRect の割り当てに従って順番に取得できます。元の式は次のとおりです。
uvRect.min.y = 1 - region.yMax / _nativeTexture.height
すると、実際の式は次のようになります。
y = (1 - startOffset.y) * nativeTexture.height - textureSize.y
それは相互作用の法則にほかなりません。パブリック NTexture(テクスチャ テクスチャ、Rect 領域) を復元して、受信領域パラメータを構築します
オフセットとサイズを取得したら、RenderTexture を使用して小さなイメージを読み取るだけです。
RenderTexture renderTex = RenderTexture.GetTemporary(nativeTexture.width, nativeTexture.height, 24, RenderTextureFormat.Default, RenderTextureReadWrite.Linear);
Graphics.Blit(nativeTexture, renderTex);
RenderTexture previous = RenderTexture.active;
RenderTexture.active = renderTex;
Texture2D resultTexture = new Texture2D(textureSize.x, textureSize.y, nativeTexture.format, false);
resultTexture.ReadPixels(new Rect((int)startOffset.x, (int)startOffset.y, textureSize.x, textureSize.y), 0, 0);
resultTexture.Apply();
RenderTexture.active = previous;
RenderTexture.ReleaseTemporary(renderTex);
回転したアルバム内の小さな写真を元に戻すにはどうすればよいですか?
Texture2D.GetPixel および Texture2D.SetPixel インターフェイスは、読み取りと書き込みが非常に遅いです。GetPixelData
または GetPixels を直接使用して、画像データ配列をエクスポートできます。操作が完了したら、画像データを更新します。次に従って読み取るには、
Color または Color32 形式を使用します。 NativeTexture.format タイプ。
var colorArray = resultTexture.GetPixelData<Color32>(0)
配列を取得したら、配列データを 90 度逆回転して、元の小さな画像を取得します。
for (int i = 0; i < textureSize.x; i++)
{
for (int j = 0; j < textureSize.y; j++)
{
colors[i * textureSize.y + j] = colorArray[textureSize.x - 1 - i + j * textureSize.x];
}
}
完全なコード
public Texture GetTexture(string url)
{
PackageItem packageItem = UIPackage.GetItemByURL(url);
if (packageItem == null)
return null;
NTexture nTexture = packageItem.texture;
Texture2D nativeTexture = nTexture.nativeTexture as Texture2D;
var startOffset = nTexture.uvRect.min;
var textureSize = new Vector2Int(nTexture.width, nTexture.height);
if (nTexture.rotated)
textureSize = new Vector2Int(nTexture.height, nTexture.width);
startOffset.x *= nativeTexture.width;
startOffset.y = (1 - startOffset.y) * nativeTexture.height - textureSize.y;
RenderTexture renderTex = RenderTexture.GetTemporary(nativeTexture.width, nativeTexture.height, 24, RenderTextureFormat.Default, RenderTextureReadWrite.Linear);
Graphics.Blit(nativeTexture, renderTex);
RenderTexture previous = RenderTexture.active;
RenderTexture.active = renderTex;
Texture2D resultTexture = new Texture2D(textureSize.x, textureSize.y, nativeTexture.format, false);
resultTexture.ReadPixels(new Rect((int)startOffset.x, (int)startOffset.y, textureSize.x, textureSize.y), 0, 0);
resultTexture.Apply();
RenderTexture.active = previous;
RenderTexture.ReleaseTemporary(renderTex);
if (nTexture.rotated)
{
var colorArray = resultTexture.GetPixelData<Color32>(0);
Texture2D rotationTexture = new Texture2D(textureSize.y, textureSize.x, nativeTexture.format, false);
var colors = rotationTexture.GetPixelData<Color32>(0);
for (int i = 0; i < textureSize.x; i++)
{
for (int j = 0; j < textureSize.y; j++)
{
colors[i * textureSize.y + j] = colorArray[textureSize.x - 1 - i + j * textureSize.x];
}
}
rotationTexture.SetPixelData(colors, 0);
rotationTexture.Apply();
Object.Destroy(resultTexture);
resultTexture = rotationTexture;
}
return resultTexture;
}