使用9宫Border参数裁图

# 比如,美术直接给了一张原大小的弹框背景图,但实际该图可以做成九宫可拉伸格形式,但是美术又不愿意再重切一次,

那我们就自己来吧,先用Unity的9宫工具,框出要保留的四个角

# 然后再用工具执行下,就能得到这样一张图片

 

using System.IO;
using UnityEditor;
using UnityEngine;

public class NinePatchTool
{

    [MenuItem("Assets/根据Border参数裁一张新的9宫图")]
    static void Create9Patch()
    {
        if (null == Selection.objects || Selection.objects.Length <= 0)
            return;

        for (var i = 0; i < Selection.objects.Length; ++i)
        {
            var obj = Selection.objects[i];
            var path = AssetDatabase.GetAssetPath(obj);
            //Debug.Log($"{obj.GetType().Name}: {path}");
            var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path);
            if (null == sprite)
                continue;

            //Debug.Log($"border:{sprite.border}, rect: {sprite.rect}");
            var srcWidth = (int)sprite.rect.width;
            var srcHeight = (int)sprite.rect.height;

            var srcTempRT = RenderTexture.GetTemporary(srcWidth, srcHeight, 0, RenderTextureFormat.ARGB32);
            Graphics.SetRenderTarget(srcTempRT);
            Graphics.Blit(sprite.texture, srcTempRT);

            var ninePatchBorder = sprite.border;
            Texture2D resultTex = null;
            if ((0 != ninePatchBorder.x && 0 != ninePatchBorder.z) && (0 != ninePatchBorder.y && 0 != ninePatchBorder.w)) //四个角
            {
                //多3个像素是用于新的3x3拉伸区域
                var leftPadding = ninePatchBorder.x + 3;
                var topPadding = ninePatchBorder.y + 3;
                var rightPadding = ninePatchBorder.z;
                var bottomPadding = ninePatchBorder.w;

                resultTex = new Texture2D((int)(leftPadding + rightPadding), (int)(topPadding + bottomPadding), TextureFormat.ARGB32, false);
                resultTex.anisoLevel = 0;
                //注意: 读取是从RenderTexture, (0, 0)为左上角,写出为Texture2D, (0, 0)为左下角
                resultTex.ReadPixels(new Rect(0, srcHeight - bottomPadding, leftPadding, bottomPadding), 0, 0); //左下角
                resultTex.ReadPixels(new Rect(srcWidth - rightPadding, srcHeight - bottomPadding, rightPadding, bottomPadding), (int)leftPadding, 0); //右下角

                resultTex.ReadPixels(new Rect(0, 0, leftPadding, topPadding), 0, (int)bottomPadding); //左上角
                resultTex.ReadPixels(new Rect(srcWidth - rightPadding, 0, rightPadding, topPadding), (int)leftPadding, (int)bottomPadding); //右上角
            }
            else if (0 != ninePatchBorder.x && 0 != ninePatchBorder.z) //横向两块
            {
                var leftPadding = ninePatchBorder.x + 3;
                var rightPadding = ninePatchBorder.z;

                resultTex = new Texture2D((int)(leftPadding + rightPadding), srcHeight, TextureFormat.ARGB32, false);
                resultTex.anisoLevel = 0;
                resultTex.ReadPixels(new Rect(0, 0, leftPadding, srcHeight), 0, 0); //
                resultTex.ReadPixels(new Rect(srcWidth - rightPadding, 0, rightPadding, srcHeight), (int)leftPadding, 0); //
            }
            else if (0 != ninePatchBorder.y && 0 != ninePatchBorder.w) //竖向两块
            {
                var topPadding = ninePatchBorder.y + 3;
                var bottomPadding = ninePatchBorder.w;

                resultTex = new Texture2D(srcWidth, (int)(topPadding + bottomPadding), TextureFormat.ARGB32, false);
                resultTex.anisoLevel = 0;
                resultTex.ReadPixels(new Rect(0, srcHeight - bottomPadding, srcWidth, bottomPadding), 0, 0); //
                resultTex.ReadPixels(new Rect(0, 0, srcWidth, (int)topPadding), 0, (int)bottomPadding); //
            }
            else
            {
                Debug.Log($"Sprite的Border不符合条件: 需要L, R均不为0或T, B均不为0: {ninePatchBorder}");
                continue;
            }

            resultTex.Apply();
            var bytes = resultTex.EncodeToPNG();

            Graphics.SetRenderTarget(null);
            RenderTexture.ReleaseTemporary(srcTempRT);

            var resultFilePath = path.Substring(0, path.Length - 4) + "_9.png";
            Debug.Log($"{resultFilePath}");
            File.WriteAllBytes(resultFilePath, bytes);

            AssetDatabase.ImportAsset(resultFilePath, ImportAssetOptions.ForceUpdate);
            //AssetDatabase.ImportAsset(resultFilePath, ImportAssetOptions.Default);
            //修改设置
            var texImporter = AssetImporter.GetAtPath(resultFilePath) as TextureImporter;
            if (texImporter)
            {
                texImporter.textureType = TextureImporterType.Sprite;
                texImporter.mipmapEnabled = false;
                texImporter.alphaIsTransparency = true;

                var setting = new TextureImporterSettings();
                texImporter.ReadTextureSettings(setting);
                setting.spriteGenerateFallbackPhysicsShape = false;
                setting.spriteBorder = ninePatchBorder; //自动处理好9宫区域
                texImporter.SetTextureSettings(setting);

                texImporter.SaveAndReimport();
                //EditorUtility.SetDirty(texImporter);
            }
        }
        //AssetDatabase.Refresh();

        Debug.Log($"finish");
    }
}

 

# 也可以只裁横向或竖向

横向裁掉一块区域

裁掉后

 

竖向裁掉

裁掉后

 

posted @ 2022-10-29 01:25  yanghui01  阅读(80)  评论(0)    收藏  举报