unity 编辑器时读取FairyGUI图集单个图像

原因

想要在编辑器扩展也能访问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

无非就是交互律。还原public NTexture(Texture texture, Rect region) 构造传入来的region参数

获得偏移和大小后只需要使用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导出图像数据数组,操作完成后刷新图像数据
根据 nativeTexture.format 类型使用Color或者Color32格式读取

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;
    }

你可能感兴趣的:(unity3d,unity,游戏引擎,FairyGUI,Editor)