一个简单的工具,对Unity下的图片做批量压缩处理,主要有以下功能:
自动取消 "Generte Mip Maps" 勾选;
针对文件夹批量自动(或手动选择压缩格式)设置图片压缩并自动保存;
单个图片文件的压缩设置;
使用方法,右键单张图片(或者包含图片的文件夹)
会打开一个设置窗口 如下,窗口里会显示当前选中的文件(文件夹)
如果是自动模式,直接点击 [设置] 按钮即可,然后等待压缩完成.这个过程与 (机器配置,压缩的图片大小,个数)有关,也许会有一点长;
完成的图片会显示打印信息
手动模式(取消勾选 [自动设置])下,下拉列表会显示压缩格式选项(我只加了这几个,有需求的可自己在代码里添加其他,注意值要与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
}
有注释,有些地方需要注意的都写了注释的;
后续:
自动压缩没有判断图片是否支持ETC和ETC2,所以可能会出现无法压缩的情况;
手动设置可能出现的问题,带 alpha 通道的和不带alpha通道的图最好分文件夹单独处理;
写完才发现单张图处理用工具反而有点多余😂,直接在编辑器里设置不就行了,哎;
参考文章: Unity中批量修改图片压缩格式 勾选Override for Android Override for iOS项 - 新一代的开山怪 - 博客园 (cnblogs.com)