Unity 编辑器工具之批量设置图片压缩

news2024/11/18 4:42:21

一个简单的工具,对Unity下的图片做批量压缩处理,主要有以下功能:

  1. 自动取消 "Generte Mip Maps" 勾选;

  1. 针对文件夹批量自动(或手动选择压缩格式)设置图片压缩并自动保存;

  1. 单个图片文件的压缩设置;

使用方法,右键单张图片(或者包含图片的文件夹)

会打开一个设置窗口 如下,窗口里会显示当前选中的文件(文件夹)

如果是自动模式,直接点击 [设置] 按钮即可,然后等待压缩完成.这个过程与 (机器配置,压缩的图片大小,个数)有关,也许会有一点长;

完成的图片会显示打印信息

手动模式(取消勾选 [自动设置])下,下拉列表会显示压缩格式选项(我只加了这几个,有需求的可自己在代码里添加其他,注意值要与unity提供的压缩枚举值保持一一对应)

代码就一个脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System;
using Object = UnityEngine.Object;

public class TextureSetEditor : ScriptableWizard
{

    static string curPlatform = "";
    static string curSelect = "";
    static string selectFormatTypeName = "";
    static int selectFormatType = 4;
    static bool autoSet = false;
    static TextureImporterFormat myFormat = TextureImporterFormat.RGBA32;
    static string Log = "";

    Vector2 scrollPos;

    enum ImgType
    {
        png = 0,
        jpg = 1,
    }

    static ImgType _imgType = ImgType.png;
    static int[] formatSize = new int[] { 32, 64, 128, 256, 512, 1024, 2048 };

    static Action SetImage = null;

    /// <summary>
    /// 压缩格式,需与TextureImporterFormat里的值保持一致
    /// 暂时列举常用的几个
    /// ETC:不支持透明通道,图片宽高必须是2的整数次幂
    /// ETC2:是ETC的扩展,支持透明通道,且图片宽高只要是4的倍数即可
    /// ASTC是Android和IOS平台下的一种高质量压缩方式,支持Android5.0和iPhone6以上机型
    /// </summary>
    enum FormatType
    {
        RGBA32 = 4,

        ETC_RGB4 = 34,
        ETC2_RGB4 = 45,
        ETC2_RGBA8 = 47,

        ASTC_RGB_5x5 = 49,
        ASTC_RGB_6x6 = 50,
        ASTC_RGB_8x8 = 51,

        ASTC_RGBA_5x5 = 55,
        ASTC_RGBA_6x6 = 56,
        ASTC_RGBA_8x8 = 57,
    }

    

    [Obsolete][MenuItem("Assets/设置图片压缩格式")]
    public static void CreateWindow()
    {
        DisplayWizard<TextureSetEditor>("设置图片压缩格式", "完成", "设置");
        GetPlatform();
        SetTextureBySelect();
    }


    void OnWizardCreate()
    {
        Debug.Log("设置完成");
    }

    protected override bool DrawWizardGUI()
    {
        //打印当前平台
        GUILayout.Label("当前平台是:" + curPlatform);
        GUILayout.Label("当前选中的是:" + curSelect);
        GUILayout.Label("===============================");

        GUILayout.Space(10);

        autoSet = GUILayout.Toggle(autoSet, "自动设置");
        if (!autoSet)
        {
            GenericMenu formatType = new GenericMenu();
            foreach (var type in Enum.GetValues(typeof(FormatType)))
            {
                string s = Enum.GetName(typeof(FormatType), type);
                formatType.AddItem(new GUIContent(s), false, SelsetFormat, (int)type);
            }

            GUILayout.Label("ETC:不支持透明通道,图片宽高必须是2的整数次幂" +
                "\nETC2:是ETC的扩展,支持透明通道,且图片宽高只要是4的倍数即可" +
                "\nASTC: 是Android和IOS平台下的一种高质量压缩方式,支持Android5.0和iPhone6以上机型");
            if (GUILayout.Button("选择压缩格式 " + selectFormatTypeName))
            {
                formatType.ShowAsContext();
            }
        }

        //添加卷轴内打印
        GUILayout.BeginHorizontal();
        GUILayout.Space(50);
        scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.Width(500),GUILayout.Height(300));
        GUILayout.Label(Log);
        GUILayout.EndScrollView();
        GUILayout.EndHorizontal();

        GUILayout.Space(150);

        return base.DrawWizardGUI();
    }

    private void OnWizardOtherButton()
    {
        if (SetImage != null)
        {
            Debug.Log("开始设置");
            SetImage();
        }
    }

    //获取正式的压缩类型
    static void SelsetFormat(object type)
    {
        selectFormatType = (int)type;
        selectFormatTypeName = Enum.GetName(typeof(FormatType), selectFormatType);
        myFormat = (TextureImporterFormat)(Enum.Parse(typeof(TextureImporterFormat), selectFormatType.ToString()) as Enum);
        Debug.Log("myFormat = " + myFormat);
    }
    
    /// <summary>
    /// 区分选中的是文件还是文件夹,分别处理
    /// </summary>
    [Obsolete]
    public static void SetTextureBySelect()
    {
        var selects = Selection.GetFiltered<Object>(SelectionMode.Assets);
        foreach (var item in selects)
        {
            string path = AssetDatabase.GetAssetPath(item);
            curSelect = path;
            if (File.Exists(path))
            {
                Debug.Log("选中的文件");
                if (CheckImageType(path))
                {
                    curSelect = curSelect + " 文件";
                    SetImage = () => {
                        SetOneImageFormat(path);
                    };
                }
            }
            else if (Directory.Exists(path))
            {
                Debug.Log("选中的文件夹");
                curSelect = curSelect + " 文件夹";
                SetImage = () => {
                    SetFloderImageFormat(path);
                };
            }
        }
    }

   
    /// <summary>
    /// 设置单张图片压缩格式
    /// </summary>
    /// <param name="path"></param>
    [Obsolete]
    static void SetOneImageFormat(string path)
    {
        //判断图片大小
        Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
        if (texture != null)
        {
            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            
            int textureSize = Mathf.Max(texture.height, texture.width);
            //Debug.Log(textureSize);
            int sizeType = FitSize(textureSize);

            //设置图片压缩格式
            TextureSetting(importer, sizeType);

        }
        else
        {
            Debug.Log("Texture2D为null:" + path);
        }
    }

    /// <summary>
    /// 设置文件夹下所有图片压缩格式
    /// </summary>
    /// <param name="path"></param>
    [System.Obsolete]
    static void SetFloderImageFormat(string selFloder)
    {
        DirectoryInfo root = new DirectoryInfo(selFloder);
        SetFloder(root);
    }


    [System.Obsolete]
    static void TextureSetting(TextureImporter texture, int size = 2048)
    {
        // 取消勾选 "Generte Mip Maps"
        texture.mipmapEnabled = false;
        //设置像素密度
        texture.spritePixelsPerUnit = 100;

#if UNITY_ANDROID && UNITY_EDITOR
        AndroidSetting(texture, size);
#elif UNITY_IOS && UNITY_EDITOR
        IOSSetting(texture, size);
#endif
        //保存修改
        texture.SaveAndReimport();
    }

    [System.Obsolete]
    static void AndroidSetting(TextureImporter texture, int size)
    {
        Debug.Log("安卓图片设置");
        var set = texture.GetPlatformTextureSettings("Android");
        set.overridden = true;

        /*备注--
         ETC:不支持透明通道,图片宽高必须是2的整数次幂
         ETC2:是ETC的扩展,支持透明通道,且图片宽高只要是4的倍数即可
         ASTC是Android和IOS平台下的一种高质量压缩方式,支持Android5.0和iPhone6以上机型
        */

        if (autoSet)
        {
            if (_imgType == ImgType.jpg)
            {
                set.format = TextureImporterFormat.ETC2_RGB4;
            }
            else if (_imgType == ImgType.png)
            {
                set.format = TextureImporterFormat.ETC2_RGBA8;
            }
        }
        else
        {
            set.format = myFormat;
        }
        
        set.maxTextureSize = size;
        set.compressionQuality = 100;
        texture.SetPlatformTextureSettings(set);
        string s = "处理图片" + texture.assetPath + "完成";
        AddLog(s);
    }

    [System.Obsolete]
    static void IOSSetting(TextureImporter texture, int size)
    {
        Debug.Log("iOS图片设置");

        var set = texture.GetPlatformTextureSettings("iOS");
        set.overridden = true;

        if (autoSet)
        {
            if (_imgType == ImgType.jpg)
            {
                set.format = TextureImporterFormat.ASTC_RGB_5x5;
            }
            else if (_imgType == ImgType.png)
            {
                set.format = TextureImporterFormat.ASTC_RGBA_5x5;
            }
        }
        else
        {
            set.format = myFormat;
        }
        
        set.maxTextureSize = size;
        set.compressionQuality = 100;
        texture.SetPlatformTextureSettings(set);
    }

    #region --辅助方法--

    /// <summary>
    /// 获取当前平台
    /// </summary>
    static void GetPlatform()
    {
#if UNITY_EDITOR && UNITY_ANDROID
        curPlatform = "Android";
#elif UNITY_EDITOR && UNITY_IOS
        curPlatform = "iOS";
#else
        curPlatform = "Other";
#endif

    }


    /// <summary>
    /// 检查图片后缀格式(根据情况而定,可自己添加其他格式)
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    static bool CheckImageType(FileInfo f)
    {
        if (f.FullName.EndsWith(".jpg") || f.FullName.EndsWith(".JPG"))
        {
            _imgType = ImgType.jpg;
            return true;
        }
        else if (f.FullName.EndsWith(".png") || f.FullName.EndsWith(".PNG"))
        {
            _imgType = ImgType.png;
            return true;
        }

        return false;
    }

    static bool CheckImageType(string path)
    {
        if (path.EndsWith(".jpg") || path.EndsWith(".JPG"))
        {
            _imgType = ImgType.jpg;
            return true;
        }
        else if (path.EndsWith(".png") || path.EndsWith(".PNG"))
        {
            _imgType = ImgType.png;
            return true;
        }

        return false;
    }


    /// <summary>
    /// 获取最合适的大小
    /// </summary>
    /// <param name="picValue"></param>
    /// <returns></returns>
    static int FitSize(int picValue)
    {
        foreach (var one in formatSize)
        {
            if (picValue <= one)
            {
                return one;
            }
        }
        return 1024;
    }


    /// <summary>
    /// 递归文件夹
    /// </summary>
    /// <param name="root"></param>
    [System.Obsolete]
    static void SetFloder(DirectoryInfo root)
    {
        GetFile(root);
        //查找子文件夹
        DirectoryInfo[] array = root.GetDirectories();
        foreach (DirectoryInfo item in array)
        {
            SetFloder(item);
        }
    }


    [System.Obsolete]
    static void GetFile(DirectoryInfo root)
    {
        FileInfo[] fileDic = root.GetFiles();
        foreach (var file in fileDic)
        {
            if (CheckImageType(file))
            {
                SetOneImageFormat(file.FullName.Replace(Application.dataPath.Replace("Assets", "").Replace("/", @"\"), ""));
            }
        }
    }


    static void AddLog(string s)
    {
        Log += (s + "\n");
    }

    #endregion

}

有注释,有些地方需要注意的都写了注释的;

后续:

  1. 自动压缩没有判断图片是否支持ETC和ETC2,所以可能会出现无法压缩的情况;

  1. 手动设置可能出现的问题,带 alpha 通道的和不带alpha通道的图最好分文件夹单独处理;

  1. 写完才发现单张图处理用工具反而有点多余😂,直接在编辑器里设置不就行了,哎;

  1. 参考文章: Unity中批量修改图片压缩格式 勾选Override for Android Override for iOS项 - 新一代的开山怪 - 博客园 (cnblogs.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/348772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue笔记(2)——页面渲染与数据收集

一、条件渲染 v-show v-if 1. v-show 2. v-if v-else的块和v-if的块间不能有中断&#xff0c;否则无效 3. v-if与template配合 当同时条件渲染多个元素时&#xff0c;可以将v-if与template的配合使用&#xff0c;若条件值为false&#xff0c;vue模板解析时会直接去掉这一块…

AcWing语法基础课笔记 第二章 printf语句与C++中的判断结构

第二章 printf语句与C中的判断结构 学习语言最好的方式就是实践&#xff0c;每当掌握一个新功能时&#xff0c;就要立即将这个功能应用到实践中。 ——闫学灿 一、printf输出格式 注意&#xff1a;使用printf 时最好添加头文件 #include <cstdio>。 Int、float、double、…

基于共聚焦显微技术的显微镜和荧光显微镜的区别

荧光显微镜主要应用在生物领域及医学研究中&#xff0c;能得到细胞或组织内部微细结构的荧光图像&#xff0c;在亚细胞水平上观察诸如Ca2 、PH值&#xff0c;膜电位等生理信号及细胞形态的变化&#xff0c;是形态学&#xff0c;分子生物学&#xff0c;神经科学&#xff0c;药理…

GEE学习笔记 八十九:在自己的APP中使用绘制矢量(中)

这一篇先讲一下ui.Map.GeometryLayer(...)&#xff0c;也就是生成显示的绘制矢量图形图层&#xff0c;具体来讲就是地图上左上角绘制的图形后添加的图层。 1、什么是GeometryLayer&#xff1f; &#xff08;1&#xff09;直接在地图上加载定义的图层 //1. add normal layer …

基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【二】【整合springSecurity】

1、创建数据库 注意&#xff1a;mysql默认字符集为utf8&#xff0c;默认排序规则为utf8_general_ci。一般我们也会选择字符集为utf-8 MySQL在5.5.3之后增加了这个utf8mb4的编码&#xff0c;utf8mb4完全向下兼容utf8&#xff0c;为了节省空间&#xff0c;一般情况下使用utf8也就…

中国国家级地面气象站基本气象要素日值数据集(V3.0)

数据集摘要 数据集包含了中国基本气象站、基准气候站、一般气象站在内的主要2474个站点1951年1月以来本站气压、气温、降水量、蒸发量、相对湿度、风向风速、日照时数和0cm地温要素的日值数据。数据量为21.3GB。 (1)SURF_CLI_CHN_MUL_DAY-TEM-12001-201501.TXT 气温数据TEM, 包…

央行数据-一款查逆回购 LPR 货币供应量 资产负债表 Shibor 数据的专业工具

自己开发的APP, App Store搜索"央行数据" 即可下载欢迎大家下载,给修改意见逆回购、正回购、MLF、票据&#xff0c;俗称央行发钱房贷基准利率多少? M2/M1/M0, 资产负债表,Shibor 了解下这款APP是经济,投资理财,股市,房价分析参考利器适用于关注经济、货币政策的用户…

第五章.与学习相关技巧—权重初始值(随机初始值,Xavier初始值,He初始值)

第五章.与学习相关技巧 5.2 权重初始值 本节将介绍权重初始值的推荐值&#xff0c;并通过实验确认神经网络的学习是否会快速进行。 1.权值衰减 权值衰减就是一种以减少权重参数的值为目的进行学习的方法&#xff0c;通过减少权重参数值来抑制过拟合的情况发生。 2.权重初始值不…

表现良好的最长时段[前缀和思想子数组]

前缀和与最长子数组前言一、表现良好的最长时间段二、前缀和思想&子数组1、前缀和&map2、前缀和&单调栈总结参考文献前言 对于子数组/子串问题&#xff0c;紧密连续前缀和/滑动窗口/单调栈&#xff1b;挖掘内在规律&#xff0c;可以简化代码&#xff0c;降低时空复…

Python多进程同步——文件锁

多个进程共享同一份资源&#xff08;共享内存、文件等&#xff09;时&#xff0c;会涉及到资源竞争问题。为了解决这种问题&#xff0c;一般采取的措施是进程在访问资源前加锁保护&#xff0c;避免多个进程同时读写。本文介绍的Python文件锁可以用来解决多进程的同步问题。 目录…

天荒地老修仙功-第六部第二篇:Spring Cloud Eureka自我保护机制

Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%&#xff0c;如果低于 85%&#xff0c;Eureka Server 会将这些实例保护起来&#xff0c;让这些实例不会过期&#xff0c;但是在保护期内如果服务刚好这个服务提供者非正常下线了&#xff0c;此时服务消…

[SCTF2019]babyre 题解

对未来的真正慷慨&#xff0c;是把一切献给现在。 ——加缪 目录 1.查壳 2.处理花指令&#xff0c;找到main函数 这一操作过程可以参考下面的视频&#xff1a; 3.静态分析第一部分,psword1 4.静态分析第二部分,psword2 5.静态分析第五部分&#xff0c;psword3 6.根据ps…

国产Linux操作系统读写RFID、NFC、IC卡示例源码

Windows系统应该是我们接触最多、最为熟悉的电脑端操作系统。Windows操作系统只能安装在x86指令集的CPU电脑中&#xff0c;x64是x86的升级版&#xff0c;Intel、Amd是x86指令集CPU最大的2个生产商。Windows系统下&#xff0c;外设接口驱动一般都封装成DLL动态库内&#xff0c;通…

基于springboot开发众筹平台前后台管理系统【完整源码+数据库+运行指导】

一、项目简介 本项目是一套基于springboot开发众筹平台前后台管理系统&#xff0c;主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目可以直接作为bishe使用。 项目都经过严格调试&#…

2023csoj寒假训练10

csoj寒假训练10 A 并查集 两个黑球之间距离不够这个白球通过的话&#xff0c;视为一个集合 考虑怎样维护这样两两之间的关系&#xff0c;我们使用并查集 同时黑球与直线的关系也要做一次维护 最后可以直接判断是否上下两条直线是否在一个集合里面 如果在一个集合里面说明…

Spring容器演示——采用Spring配置文件管理Bean

一、创建Maven项目 创建Maven项目 - SpringDemo&#xff0c;设置项目位置以及组ID 修改项目的Maven配置 二、添加Spring依赖 在Maven仓库里查找Spring框架&#xff08;https://mvnrepository.com&#xff09; 查看Spring Core 选择版本 - 5.3.25 添加到pom.xml文件的元…

盘点程序员都不一定知道的小众网站!建议收藏,java编程必备!

俗话说的好&#xff0c;有一个趁手的工具解决了80%的疑虑。作为智慧物种的新新人类&#xff0c;手上掌握一两个不为人知的好用网站已经是件稀疏平常的事情。 今天我们就一起来看看&#xff0c;有哪些小众网站是程序员必备的&#xff01; 业内人士都知道&#xff0c;一直劈里啪…

windows下面安装Python和pip终极教程

Python的语言风格很nice&#xff0c;但是这门语言对于windows并不算很友好&#xff0c;因为如果是初学者在windows环境下安装&#xff0c;简直是折磨人&#xff0c;会遇到各种蛋疼的情况。本文希望提供傻瓜式的教程&#xff0c;能够令读者成功安装Python和pip。 第一步&#xf…

什么是push通知栏消息?

我是3y&#xff0c;一年CRUD经验用十年的markdown程序员&#x1f468;&#x1f3fb;‍&#x1f4bb;常年被誉为职业八股文选手 今天继续更新Austin&#xff0c;给Austin新增一个发送渠道&#xff08;PUSH通知栏推送&#xff09; Push通知栏消息是非常常见的&#xff0c;几乎每…

【elementUI】自定义封装el-upload上传内容

文章目录为实现如图所示功能&#xff0c;点击第一步弹出模态框&#xff0c;第二部将所有文件导入&#xff0c;第三步点击确定的时候上传到后台接口&#xff0c;封装一个组件 1.搭建template <div style"display: inline-block; margin-left: 10px;"><el-bu…