UIAltas贴图 RGB+Alpha图片分离方法

接上文:这次主要提供了分离贴图的方法。废话不多说,上代码,里面都有注释。

using System.IO;
using UnityEditor;
using UnityEngine;


public class TextureHandler
{
    //来给工具一个快捷键
    [MenuItem("Tools/NGUI/ETC1+Alpha", false, 11)]
    static void SingleCreateUIAtlasPrefab()
    {
        CreateUIAtlasPrefab(Selection.activeObject);
        AssetDatabase.Refresh();
    }
    
    private static void CreateUIAtlasPrefab(Object ob)
    {
        string path = AssetDatabase.GetAssetPath(ob);
        if (string.IsNullOrEmpty(path) || !isTextureFile(path))
        {
            Debug.LogError("未选择图片或者选中的对象不是图片");
            return;
        }


        if (Path.GetExtension(path) == ".png" && !path.Contains("_Alpha") && !path.Contains("_RGB"))
        {
            ShowProgress(path, 0.5f);


            #region 根据图片创建材质对象
            //需要特定的Shader,将分离成的ETC1+Alpha贴图进行叠加
            Material mat = new Material(Shader.Find("UI/UI_ETC"));
            mat.name = ob.name;
            AssetDatabase.CreateAsset(mat, path.Replace(".png", ".mat"));
            
            //设置图片可读
            SetTextureReadable(path);
            //分离图片 RGB+Alpha
            SeperateRGBAndAlpha(path);


            //设置原图
            TextureSetting(path, TextureImporterType.Advanced, TextureImporterFormat.ETC_RGB4, false);


            //给材质赋值贴图信息
            Texture2D _mainTex = AssetDatabase.LoadAssetAtPath(path.Replace(".png", "_RGB.png"), typeof(Texture2D)) as Texture2D;
            Texture2D _alphaTex = AssetDatabase.LoadAssetAtPath(path.Replace(".png", "_Alpha.png"), typeof(Texture2D)) as Texture2D;
            mat.SetTexture("_MainTex", _mainTex);
            mat.SetTexture("_AlphaTex", _alphaTex);
            #endregion


            #region Atlas信息赋值
            GameObject go = null;
            UIAtlas uiAtlas = null;


            if ((go = AssetDatabase.LoadAssetAtPath(path.Replace(".png", ".prefab"), typeof(GameObject)) as GameObject) != null)
            {
                //如果有Atlas图集,那么修改图集信息
                uiAtlas = SetAtlasInfo(go, path, mat);
            }
            else
            { 
                //如果没有Atlas图集,就创建图集
                go = new GameObject(ob.name);
                go.AddComponent<UIAtlas>();
                uiAtlas = SetAtlasInfo(go, path, mat);


                //创建Atlas预制体
                CreatAtlasPrefab(go, ob.name, path);
            }


            #endregion


            //完毕!
            AssetDatabase.SaveAssets();
            EditorUtility.ClearProgressBar();
        }


    }


    /// <summary>
    /// 创建预制体
    /// </summary>
    /// <returns></returns>
    static Object CreatAtlasPrefab(GameObject go, string name, string path)
    {
        Object tmpPrefab = PrefabUtility.CreateEmptyPrefab(path.Replace(".png", ".prefab"));
        tmpPrefab = PrefabUtility.ReplacePrefab(go, tmpPrefab, ReplacePrefabOptions.ConnectToPrefab);
        Object.DestroyImmediate(go);
        return tmpPrefab;
    }




    /// <summary>
    /// 设置图集信息
    /// </summary>
    static UIAtlas SetAtlasInfo(GameObject go, string path, Material mat)
    {
        if (AssetDatabase.LoadAssetAtPath(path.Replace(".png", ".txt"), typeof(TextAsset)))
        {
            UIAtlas uiAtlas = go.GetComponent<UIAtlas>();
            uiAtlas.spriteMaterial = mat;


            
            TextAsset ta = AssetDatabase.LoadAssetAtPath(path.Replace(".png", ".txt"), typeof(TextAsset)) as TextAsset;
            NGUIJson.LoadSpriteData(uiAtlas, ta);
            uiAtlas.MarkAsChanged();
            return uiAtlas;
        }
        return null;
    }




    public static float sizeScale = 1f;
    /// <summary>
    /// 分离RGB和Alpha
    /// </summary>
    /// <param name="texturePath"></param>
    static void SeperateRGBAndAlpha(string texturePath)
    {
        Texture2D sourcetex = AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)) as Texture2D;
        if (!sourcetex)
        {
            Debug.LogError("没有找到图片 : " + texturePath);
            return;
        }


        //创建贴图
        Texture2D rgbTex = new Texture2D(sourcetex.width, sourcetex.height, TextureFormat.RGB24, true);
        Texture2D alphaTex = new Texture2D((int)(sourcetex.width * sizeScale), (int)(sourcetex.height * sizeScale), TextureFormat.RGB24, true);


        for (int i = 0; i < sourcetex.width; i++)
        {
            for (int j = 0; j < sourcetex.height; j++)
            {
                //获取像素颜色
                Color color = sourcetex.GetPixel(i, j);
                //RGB
                Color rgbColor = color;
                //Alpha
                Color alphaColor = color;
                alphaColor.r = color.a;
                alphaColor.g = color.a;
                alphaColor.b = color.a;
                //设置像素颜色
                rgbTex.SetPixel(i, j, rgbColor);
                alphaTex.SetPixel((int)(i * sizeScale), (int)(j * sizeScale), alphaColor);


            }
        }


        rgbTex.Apply();
        alphaTex.Apply();


        //创建图片
        byte[] bytes = rgbTex.EncodeToPNG();
        WriteToPNG(texturePath.Replace(".png", "_RGB.png"), bytes);
        bytes = alphaTex.EncodeToPNG();
        WriteToPNG(texturePath.Replace(".png", "_Alpha.png"), bytes);




        Debug.Log("成功分离图片:" + texturePath);
    }






    static void WriteToPNG(string path, byte[] bytes)
    {
        File.WriteAllBytes(path, bytes);
        AssetDatabase.Refresh();
        TextureSetting(path, TextureImporterType.Advanced, TextureImporterFormat.ETC_RGB4, false);
    }


    /// <summary>
    /// 设置图片格式
    /// </summary>
    static void TextureSetting(string path, TextureImporterType mTextureImporterType = TextureImporterType.Advanced, TextureImporterFormat mTextureImporterFormat = TextureImporterFormat.RGBA32, bool readEnable = false)
    {
        //纹理导入器
        TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
        if (textureImporter == null) return;


        textureImporter.textureType = mTextureImporterType;
        if (textureImporter.textureType == TextureImporterType.Advanced)
        {
            textureImporter.spriteImportMode = SpriteImportMode.None;
            textureImporter.mipmapEnabled = false;
            textureImporter.isReadable = readEnable;
            textureImporter.alphaIsTransparency = false;
        }
        else if (textureImporter.textureType == TextureImporterType.Sprite)
        {
            textureImporter.mipmapEnabled = false;
        }


        textureImporter.SetPlatformTextureSettings("Android", 2048, mTextureImporterFormat);
        textureImporter.SetPlatformTextureSettings("Windows", 2048, mTextureImporterFormat);
        textureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGB4);


        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }




    /// <summary>
    /// 设置纹理格式
    /// </summary>
    /// <param name="path"></param>
    static void SetTextureReadable(string path)
    {
        //纹理导入器
        TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
        if (textureImporter == null) return;
        textureImporter.textureType = TextureImporterType.Advanced;
       
        //设置纹理可写
        textureImporter.isReadable = true;
        //导入指定路径资源
        AssetDatabase.ImportAsset(path);
    }




    /// <summary>
    /// 显示进度条
    /// </summary>
    /// <param name="path"></param>
    /// <param name="val"></param>
    static void ShowProgress(string path, float val)
    {
        EditorUtility.DisplayProgressBar("批量处理中...", string.Format("Please wait...  Path:{0}", path), val);
    }


    /// <summary>
    /// 判断是否是图片
    /// </summary>
    /// <param name="_path"></param>
    /// <returns></returns>
    static bool isTextureFile(string _path)
    {
        string path = _path.ToLower();
        return path.EndsWith(".psd") || path.EndsWith(".tga") || path.EndsWith(".png") || path.EndsWith(".jpg") || path.EndsWith(".dds") || path.EndsWith(".bmp") || path.EndsWith(".tif") || path.EndsWith(".gif");
    }
}



这里需要注意的一点是:这里需要配合特定的Shader,对RGB+Alpha进行分别的采样叠加,最终输出对应的像素。具体Shader会在接下来的博客中进行分享。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值