批量压缩纹理

最近在做Unity转微信小游戏的工作,微信小游戏对包体大小优化要求较高,而纹理图片资源向来是包体大小占用的大头,本篇记录一下批量压缩纹理资源的工具。

Unity各平台支持的纹理压缩格式
Unity2021开始支持ASTC压缩格式,因此针对微信小游戏最好使用Unity2021及以上版本能得到最好的纹理压缩支持。

using System;
using System.IO;
using System.Reflection;
using UnityEngine;
using UnityEditor;


public class SpriteImporter : AssetPostprocessor
{
    
    
    [MenuItem("Assets/Custom Reimport Images")]
    static void SetAllTextureType()
    {
    
    
        //获取鼠标点击目录
        var arr = Selection.GetFiltered(typeof(DefaultAsset), SelectionMode.Assets);
        string folder = AssetDatabase.GetAssetPath(arr[0]);
        Debug.Log($"Reimport Path: {
      
      folder}");
        
        DirectoryInfo direction = new DirectoryInfo(folder);
        FileInfo[] pngFiles = direction.GetFiles("*.png", SearchOption.AllDirectories);
        FileInfo[] jpgFiles = direction.GetFiles("*.jpg", SearchOption.AllDirectories);

        try
        {
    
     
            SetTexture(pngFiles);
            SetTexture(jpgFiles);
        }
        catch (Exception e)
        {
    
    
            Debug.Log(e);
            throw;
        }
        finally
        {
    
    
            EditorUtility.ClearProgressBar();
            AssetDatabase.Refresh();
        }
    }

    private static void SetTexture(FileInfo[] files)
    {
    
    
        for (int i = 0; i < files.Length; i++)
        {
    
    
            //返回绝对路径
            string fullPath = files[i].FullName.Replace("\\", "/");
            //Debug.Log($"Set {fullPath}");
            //通过替换Application.dataPath为Assets变为相对路径
            string path = fullPath.Replace(Application.dataPath, "Assets");
            TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
            EditorUtility.DisplayProgressBar("批量处理图片",files[i].Name,i/(float)files.Length);
            SetTextureFormat(textureImporter);
        }
    }

    private static void SetTextureFormat(TextureImporter textureImporter)
    {
    
    
      
        textureImporter.mipmapEnabled = false;
        textureImporter.isReadable = false;
        int maxSize = GetMaxSize(textureImporter);
        TextureImporterFormat defaultAlpha;
        TextureImporterFormat defaultNoAlpha;

//这里设置要放在对应的平台代码块内,否则改变的就是默认的平台            
#if UNITY_ANDROID 
        TextureImporterPlatformSettings settings_Android = new TextureImporterPlatformSettings();
        //标识平台为Android 大小写都可以
        settings_Android.name = "Android";
        settings_Android.overridden = true;
        settings_Android.maxTextureSize = maxSize;
        bool divisibleOf4 = IsDivisibleOf4(textureImporter);
        defaultAlpha = divisibleOf4 ? TextureImporterFormat.ETC2_RGBA8 : TextureImporterFormat.ASTC_4x4;
        defaultNoAlpha = divisibleOf4 ? TextureImporterFormat.ETC2_RGB4  : TextureImporterFormat.ASTC_4x4;
        settings_Android.format = textureImporter.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNoAlpha;
        textureImporter.SetPlatformTextureSettings(settings_Android);
#elif UNITY_IOS
        TextureImporterPlatformSettings settings_IOS = new TextureImporterPlatformSettings();
        settings_IOS.name = "IOS";
        settings_IOS.overridden = true;
        settings_IOS.maxTextureSize = maxSize / 4;
        bool powerOfTwo = IsPowerOfTwo(textureImporter);
        defaultAlpha = powerOfTwo ? TextureImporterFormat.PVRTC_RGBA4 : TextureImporterFormat.ASTC_4x4;
        defaultNoAlpha = powerOfTwo ? TextureImporterFormat.PVRTC_RGB4 : TextureImporterFormat.ASTC_4x4;
        settings_IOS.format = textureImporter.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNoAlpha;
        textureImporter.SetPlatformTextureSettings(settings_IOS);
#elif UNITY_WEBGL
        TextureImporterPlatformSettings settings_WebGl = new TextureImporterPlatformSettings();
        settings_WebGl.name = "WebGL";
        settings_WebGl.overridden = true;
        settings_WebGl.maxTextureSize = (maxSize / 4) <= 32 ? 32 : maxSize / 4;
        bool divisibleOf4 = IsDivisibleOf4(textureImporter);
        defaultAlpha = divisibleOf4 ? TextureImporterFormat.DXT5Crunched : TextureImporterFormat.ASTC_4x4;
        defaultNoAlpha = divisibleOf4 ? TextureImporterFormat.DXT1Crunched : TextureImporterFormat.ASTC_4x4;
        //defaultAlpha = TextureImporterFormat.ASTC_4x4;
        //defaultNoAlpha = TextureImporterFormat.ASTC_4x4;
        settings_WebGl.format = textureImporter.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNoAlpha;
        textureImporter.SetPlatformTextureSettings(settings_WebGl);
#elif UNITY_STANDALONE
        
#endif
        //保存更改并重新导入图片
        textureImporter.SaveAndReimport();
    }

    
    private static int[] sizes = {
    
    32, 64, 128, 256, 512, 1024, 2048, 4096};

    private static int GetMaxSize(TextureImporter textureImporter)
    {
    
    
        (int width, int height) = GetTextureImporterSize(textureImporter);
        //Debug.Log($"width: {width} height: {height}");
        int tempMax = Mathf.Max(height, width);
        foreach (var size in sizes)
        {
    
    
            if (tempMax <= size)
                return size;
        }

        return 2048;
    }
    
    
    //获取导入图片的宽高
    static (int, int) GetTextureImporterSize(TextureImporter textureImporter)
    {
    
    
        if (textureImporter != null)
        {
    
    
            object[] args = new object[2];
            MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
            mi.Invoke(textureImporter, args);
            return ((int)args[0], (int)args[1]);
        }
        return (0, 0);
    }


    //长宽都被4整除
    static bool IsDivisibleOf4(TextureImporter textureImporter)
    {
    
    
        (int width, int height) = GetTextureImporterSize(textureImporter);
        return (width % 4 == 0 && height % 4 == 0);
    }

    //2的整数次幂
    static bool IsPowerOfTwo(TextureImporter textureImporter)
    {
    
    
        (int width, int height) = GetTextureImporterSize(textureImporter);
        return (width == height) && (width > 0) && ((width & (width - 1)) == 0);
    }
}

参考:
Unity批量压缩图片的功能实现
Unity 如何实现批量修改图片格式
Unity中批量修改图片压缩格式

猜你喜欢

转载自blog.csdn.net/weixin_44276280/article/details/130830888
今日推荐