Unity一键压图插件开发

前言

前段时间给项目压图,上千张图片都是一张张手动压的,累的要死还没有意义,于是就萌生了做一个unity压图插件的想法。功能逻辑不是很复杂,因为是第一次研究EditorGUI,大概有一半时间都用在制作插件界面上了。

正文

界面效果:

点击菜单栏中的 图片压缩->打开工具,会弹出插件的界面。
在这里插入图片描述
在这里插入图片描述
Talk is cheap. Show me the code.
代码如下:

using System.Collections;
using UnityEngine;
using UnityEditor;
using System.IO;
public class CompressTextureHelper : EditorWindow
{
    private enum Platform
    {
        Android,
        iPhone,
        Standalone,
        WebGL
    }

    private enum CompressMode
    {
        普通压缩, //最保守的压缩,选择比最大边大一号的size压缩,效果可能会不明显
        智能压缩, //选择最大边接近的size,比普通压缩压缩力度大
        根据面积压缩, //根据面积压缩,选择比自己面积大一号的,比较保守
        根据面积强力压缩 //根据面积压缩,选择与自己最接近的
    }

    private CompressMode mode = CompressMode.普通压缩;

    private bool isReset;

    private bool isAndroid;
    private bool isIOS;
    private bool isStandalone;
    private bool isWebGL;

    private int quality;
    private TextureImporterFormat format = TextureImporterFormat.ASTC_RGB_6x6;

    private TextureImporterPlatformSettings settings;

    //存储路径
    static ArrayList ImagePathlist;

    [MenuItem("图片压缩/打开工具")]
    static void Init()
    {
        GetWindow(typeof(CompressTextureHelper));
    }

    private void Awake()
    {
        settings = new TextureImporterPlatformSettings();
        settings.overridden = true;
        //settings.resizeAlgorithm = TextureResizeAlgorithm.Mitchell;
        //settings.textureCompression = TextureImporterCompression.Uncompressed;
        //settings.compressionQuality = 100;
        //settings.crunchedCompression = true;
        //settings.allowsAlphaSplitting = true;
        //settings.androidETC2FallbackOverride = AndroidETC2FallbackOverride.UseBuildSettings;
    }

    //界面
    void OnGUI()
    {
        EditorGUILayout.Space();
        EditorGUILayout.Space();
        EditorGUILayout.Space();
        EditorGUI.DropShadowLabel(new Rect(0, -5, position.width, 20), "一键压缩工具v1.0");
        EditorGUILayout.Space();

        EditorGUI.BeginDisabledGroup(isReset); //与end呼应,中间的都灰色禁用
        //GUI.enabled = isReset; //和上面功能类似,结束位置用GUI.enabled = true;

        mode = (CompressMode)EditorGUILayout.EnumPopup("压缩模式", mode);
        EditorGUILayout.Space();

        format = (TextureImporterFormat)EditorGUILayout.EnumPopup("压图格式", format);
        EditorGUILayout.Space();

        EditorGUI.EndDisabledGroup();
        //GUI.enabled = true;

        EditorGUILayout.LabelField("压缩平台:");
        //EditorGUILayout.BeginHorizontal(); //开始水平布局
        isAndroid = EditorGUILayout.Toggle("Android", isAndroid);
        isIOS = EditorGUILayout.Toggle("IOS", isIOS);
        isStandalone = EditorGUILayout.Toggle("PC,Mac&Linux", isStandalone);
        isWebGL = EditorGUILayout.Toggle("WebGL", isWebGL);
        //EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();

        isReset = EditorGUILayout.Toggle("还原为导入时默认格式", isReset);
        EditorGUILayout.Space();

        if (GUILayout.Button("一键压缩"))
        {
            CompressorIma();
        }
        EditorGUILayout.Space();

        if (GUILayout.Button("单个文件夹压缩"))
        {
            CompressorIma1();
        }
        EditorGUILayout.Space();

        if (GUILayout.Button("选中图片压缩"))
        {
            CompressorIma2();
        }
    }

    //获取所有图片路径并保存
    void GetDirs(string path1)
    {
        foreach (string path in Directory.GetFiles(path1))
        {
            //获取所有文件夹中后缀符合要求对象的路径  
            if (System.IO.Path.GetExtension(path) == ".jpg" || System.IO.Path.GetExtension(path) == ".png" || System.IO.Path.GetExtension(path) == ".JPG" || System.IO.Path.GetExtension(path) == ".PNG")
            {
                ImagePathlist.Add(path.Substring(path.IndexOf(path1)));
            }
        }
        if (Directory.GetDirectories(path1).Length > 0)  //遍历所有文件夹  
        {
            foreach (string path11 in Directory.GetDirectories(path1))
            {
                GetDirs(path11);
            }
        }
    }

    //处理资源
    void opImage(string path)
    {
        try
        {
            TextureImporter ti = (TextureImporter)TextureImporter.GetAtPath(path);
            Texture texture = AssetDatabase.LoadAssetAtPath<Texture>(path);

            int size = 1024;
            GetSize(texture, ref size);

            ChoosePlatformAndHandleIma(ti, size);
        }
        catch (System.Exception)
        {
            //因为某些原因未被成功压缩的图片,请手动查看路径
            Debug.LogError(path);
        }
    }

    //一键压缩
    void CompressorIma()
    {
        if (!JudgeChoose())
            return;

        if (ImagePathlist == null)
        {
            ImagePathlist = new ArrayList();
        }
        else
        {
            ImagePathlist.Clear();
        }

        GetDirs("Assets");
        
        bool temp = EditorUtility.DisplayDialog("提示", "一共需要处理" + ImagePathlist.Count + "张图片", "确定", "取消");

        if (temp)
        {
            EditorUtility.DisplayProgressBar("进度", "0/" + ImagePathlist.Count, 0);
            for (int i = 0; i < ImagePathlist.Count; i++)
            {
                opImage((string)ImagePathlist[i]);
                EditorUtility.DisplayProgressBar("进度", (i + 1) + "/" + ImagePathlist.Count, ((i + 1) / (float)ImagePathlist.Count));
            }
            EditorUtility.ClearProgressBar();
        }
        else
        {
            return;
        }
    }

    //单个文件夹压缩
    void CompressorIma1()
    {
        if (!JudgeChoose())
            return;

        object[] selection = (object[])Selection.objects;
        //判断是否有对象被选中 并且是一个对象  不带后缀的
        if (selection.Length != 1)
        {
            EditorUtility.DisplayDialog("提示", "请选择要压缩的文件夹!(要在Project视窗的右侧选取)", "确定");
            return;
        }


        string objPath = AssetDatabase.GetAssetPath((Object)selection[0]);
        if (objPath.Contains("."))
        {
            EditorUtility.DisplayDialog("提示", "不是文件夹,请重现选取!(要在Project视窗的右侧选取)", "确定");
            return;
        }

        string fullPath = objPath;

        if (ImagePathlist == null)
        {
            ImagePathlist = new ArrayList();
        }
        else
        {
            ImagePathlist.Clear();
        }

        GetDirs(fullPath);
        
        bool temp = EditorUtility.DisplayDialog("提示", "一共需要处理" + ImagePathlist.Count + "张图片", "确定", "取消");

        if (temp)
        {
            EditorUtility.DisplayProgressBar("进度", "0/" + ImagePathlist.Count, 0);
            for (int i = 0; i < ImagePathlist.Count; i++)
            {
                opImage((string)ImagePathlist[i]);
                EditorUtility.DisplayProgressBar("进度", (i + 1) + "/" + ImagePathlist.Count, ((i + 1) / (float)ImagePathlist.Count));
            }
            EditorUtility.ClearProgressBar();
        }
        else
        {
            return;
        }
    }

    //压缩选中图片
    void CompressorIma2()
    {
        if (!JudgeChoose())
            return;

        if (ImagePathlist == null)
        {
            ImagePathlist = new ArrayList();
        }
        else
        {
            ImagePathlist.Clear();
        }

        object[] selection = (object[])Selection.objects;
        
        if (selection.Length == 0)
        {
            EditorUtility.DisplayDialog("提示", "请选中要压缩的图片!", "确定");
            return;
        }

        foreach (Object obj in selection)
        {
            string objPath = AssetDatabase.GetAssetPath(obj);
            
            if (objPath.EndsWith(".jpg") || objPath.EndsWith(".png") || objPath.EndsWith(".JPG") || objPath.EndsWith(".PNG"))
            {
                ImagePathlist.Add(objPath);
            }
            else
            {
                EditorUtility.DisplayDialog("提示", "请选择正确的图片格式!", "确定");
                return;
            }
        }
        if (ImagePathlist.Count > 0)
        {
            bool temp = EditorUtility.DisplayDialog("提示", "一共需要处理" + ImagePathlist.Count + "张图片", "确定", "取消");

            if (temp)
            {
                EditorUtility.DisplayProgressBar("进度", "0/" + ImagePathlist.Count, 0);
                for (int i = 0; i < ImagePathlist.Count; i++)
                {
                    opImage((string)ImagePathlist[i]);
                    EditorUtility.DisplayProgressBar("进度", (i + 1) + "/" + ImagePathlist.Count, ((i + 1) / (float)ImagePathlist.Count));
                }
                EditorUtility.ClearProgressBar();
            }
            else
            {
                return;
            }
        }
    }

    void GetSize(Texture texture,ref int size)
    {
        if (isReset)
        {
            size = 2048;
            return;
        }

        if(mode != CompressMode.根据面积压缩 && mode != CompressMode.根据面积强力压缩)
        {
            float judge = texture.width >= texture.height ? texture.width : texture.height;

            if (judge <= 32)
            {
                size = 32;
            }
            else if (judge <= 64)
            {
                size = 64;
            }
            else if (judge <= 128)
            {
                size = 128;
            }
            else if (judge <= 256)
            {
                size = 256;
            }
            else if (judge <= 512)
            {
                size = 512;
            }
            else if (judge <= 1024)
            {
                size = 1024;
            }
            else if (judge <= 2048)
            {
                size = 2048;
            }
            else if (judge <= 4096)
            {
                size = 4096;
            }
            else if (judge <= 8192)
            {
                size = 8192;
            }
            else
            {
                size = 1024;
            }

            if (mode == CompressMode.智能压缩)
            {
                if (size - judge > judge - size / 2)
                    size /= 2;
            }
            return;
        }

        int texArea = texture.width * texture.height;

        if (texArea <= 32 * 32)
        {
            size = 32;
        }
        else if (texArea <= 64 * 64)
        {
            size = 64;
        }
        else if (texArea <= 128 * 128)
        {
            size = 128;
        }
        else if (texArea <= 256 * 256)
        {
            size = 256;
        }
        else if (texArea <= 512 * 512)
        {
            size = 512;
        }
        else if (texArea <= 1024 * 1024)
        {
            size = 1024;
        }
        else if (texArea <= 2048 * 2048)
        {
            size = 2048;
        }
        else if (texArea <= 4096 * 4096)
        {
            size = 4096;
        }
        else if (texArea <= 8192 * 8192)
        {
            size = 8192;
        }
        else
        {
            size = 1024;
        }

        if (mode == CompressMode.根据面积强力压缩)
        {
            if (size * size - texArea > texArea - size * size / 2)
                size /= 2;
            Debug.Log(size);
        }
    }

    //根据选择的平台处理图片
    void ChoosePlatformAndHandleIma(TextureImporter ti,int size)
    {
        settings.maxTextureSize = size;
        if (isReset)
        {
            settings.overridden = false;
            format = TextureImporterFormat.Automatic;
        }
        settings.format = format;
        if (isAndroid)
        {
            settings.name = Platform.Android.ToString();
            HandleIma(ti);
        }

        if (isIOS)
        {
            settings.name = Platform.iPhone.ToString();
            HandleIma(ti);
        }

        if (isStandalone)
        {
            settings.name = Platform.Standalone.ToString();
            HandleIma(ti);
        }

        //木鸡推荐的压缩方法 默认DXT1Crunched
        if (isWebGL)
        {
            settings.name = Platform.WebGL.ToString();

            if(ti.DoesSourceTextureHaveAlpha())
            {
                settings.format = TextureImporterFormat.DXT5Crunched;
            }

            settings.compressionQuality = 50;
            
            HandleIma(ti);
        }
    }

    //处理图片
    void HandleIma(TextureImporter ti)
    {
        ti.SetPlatformTextureSettings(settings);
        ti.SaveAndReimport();
    }

    //不选择输出平台提醒
    bool JudgeChoose()
    {
        if (!isAndroid && !isIOS && !isStandalone && !isWebGL)
        {
            EditorUtility.DisplayDialog("提示", "请勾选要压缩的平台!", "确定");
            return false;
        }
        return true;
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我寄人间雪满头丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值