添加图片优化工具

dev_chengFeng
Genkins 2020-07-28 17:57:02 +08:00
parent 146197b320
commit 65252cb36d
2 changed files with 374 additions and 0 deletions

View File

@ -0,0 +1,363 @@
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System.Text;
namespace LJ_OptTools
{
public class TextureSizeOptUtilities
{
public struct TextureSizeData
{
public int width;
public int height;
public SpriteMetaData[] spDatas;
}
public static bool NeedExtend(Texture2D tex, TextureImporter ti)
{
if (tex == null ||//用packingTag打图集 和 本身就是2的整数幂的 不需要处理
(ti.textureType == TextureImporterType.Sprite && !string.IsNullOrEmpty(ti.spritePackingTag))
) return false;
var oWidth = tex.width;
var oHeight = tex.height;
if (oWidth <= 0 || oHeight <= 0) return false;
var tarW = (oWidth / 4 + ((oWidth % 4 > 0) ? 1 : 0)) * 4;
var tarH = (oHeight / 4 + ((oHeight % 4 > 0) ? 1 : 0)) * 4;
return oWidth != tarW || oHeight != tarH;
}
public static TextureSizeData CalcTextureSize(Texture tex, TextureImporter ti)
{
var ret = new TextureSizeData();
var oWidth = tex.width;
var oHeight = tex.height;
#region Get Sprites Data
if (ti.spriteImportMode == SpriteImportMode.Multiple && ti.spritesheet.Length > 0) //精灵表单
{
var spData = ti.spritesheet;
var length = spData.Length;
ret.spDatas = new SpriteMetaData[length];
for (var i = 0; i < length; i++)
{
ret.spDatas[i] = spData[i];
}
}
#endregion
//图片大小调整为4的整数倍
var tarW = (oWidth / 4 + ((oWidth % 4 > 0) ? 1 : 0)) * 4;
var tarH = (oHeight / 4 + ((oHeight % 4 > 0) ? 1 : 0)) * 4;
ret.width = tarW;
ret.height = tarH;
return ret;
}
public static bool ExtendTexture( string path)
{
var tex = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
var ti = AssetImporter.GetAtPath(path) as TextureImporter;
if (!NeedExtend(tex, ti)) return false; //不是4的整数倍的才进行处理
var sizeData = CalcTextureSize(tex, ti);
var oWidth = tex.width;
var oHeight = tex.height;
var texName = tex.name;
var texFormat = ti.DoesSourceTextureHaveAlpha() ? TextureFormat.RGBA32 : TextureFormat.RGB24;
Color[] texPixels = null;
if (tex.isReadable)
{
texPixels = tex.GetPixels(0, 0, oWidth, oHeight);
}
else
{
Texture2D tmpTex = null;
var tmpRT = RenderTexture.GetTemporary(oWidth, oHeight, 0, RenderTextureFormat.ARGB32);
Graphics.Blit(tex, tmpRT);
Resources.UnloadAsset(tex);
RenderTexture.active = tmpRT;
tmpTex = new Texture2D(oWidth, oHeight, TextureFormat.ARGB32, false);
tmpTex.ReadPixels(new Rect(0, 0, oWidth, oHeight), 0, 0);
tmpTex.Apply(false, false);
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(tmpRT);
texPixels = tmpTex.GetPixels(0, 0, oWidth, oHeight);
Object.DestroyImmediate(tmpTex);
}
var tarW = sizeData.width;
var tarH = sizeData.height;
var newTex = new Texture2D(tarW, tarH, texFormat, false, true);
var defaultPixels = new Color32[tarW * tarH];
for (int j = 0, jmax = tarH * tarW; j < jmax; ++j)
{
defaultPixels[j] = Color.clear;
}
newTex.SetPixels32(defaultPixels);
newTex.Apply(true, false);
newTex.SetPixels(0, 0, oWidth, oHeight, texPixels);
newTex.Apply(true, false);
var ext = Path.GetExtension(path).ToLower();
switch (ext)
{
case ".png":
File.WriteAllBytes(path, newTex.EncodeToPNG());
break;
case ".jpg":
File.WriteAllBytes(path, newTex.EncodeToJPG());
break;
case ".tga":
File.WriteAllBytes(path, newTex.EncodeToTGA());
break;
}
Object.DestroyImmediate(newTex);
AssetDatabase.ImportAsset(path);
ti = AssetImporter.GetAtPath(path) as TextureImporter;
ti.spriteImportMode = SpriteImportMode.Multiple;
if (sizeData.spDatas == null || sizeData.spDatas.Length < 1)
{
var spData = new SpriteMetaData[1];
spData[0].name = texName;
spData[0].rect = new Rect(0f, 0f, oWidth, oHeight);
spData[0].border = Vector4.zero;
spData[0].alignment = 0;
ti.spritesheet = spData;
}
else
{
var newSPSheet = new SpriteMetaData[sizeData.spDatas.Length];
for (int i = 0; i < sizeData.spDatas.Length; i++)
{
newSPSheet[i] = sizeData.spDatas[i];
}
ti.spritesheet = newSPSheet;
}
AssetDatabase.WriteImportSettingsIfDirty(path);
AssetDatabase.ImportAsset(path);
return true;
}
public static void SettingPlantformTex(TextureImporter ti, TextureImporterPlatformSettings setting, bool useCrunched, bool pot)
{
if (!setting.overridden)
{
setting.overridden = true;
}
//带透明通道 压缩格式测试完更改
if (ti.DoesSourceTextureHaveAlpha())
{
if (useCrunched)
{
if (setting.format != TextureImporterFormat.ETC2_RGBA8Crunched)
setting.format = TextureImporterFormat.ETC2_RGBA8Crunched;
}
else
{
if (setting.format != TextureImporterFormat.ASTC_RGBA_5x5)
setting.format = TextureImporterFormat.ASTC_RGBA_5x5;
}
}
else //不带透明通道
{
if (useCrunched)
{
if (pot && setting.format != TextureImporterFormat.ETC_RGB4Crunched)
setting.format = TextureImporterFormat.ETC_RGB4Crunched;
else
setting.format = TextureImporterFormat.ETC2_RGBA8Crunched;
}
else
{
if (setting.format != TextureImporterFormat.ASTC_RGB_5x5)
setting.format = TextureImporterFormat.ASTC_RGB_5x5;
}
}
if (setting.compressionQuality < 100)
{
setting.compressionQuality = 100;
}
}
public static void SetTextureFormat( string path, bool useCrunched)
{
if (string.IsNullOrEmpty(path)) return;
var ti = AssetImporter.GetAtPath(path) as TextureImporter;
if (ti == null)
{
Debug.LogWarning("Can load TextureImporter:" + path);
return;
}
if (ti.textureShape != TextureImporterShape.Texture2D)
{
return;
}
var pAndSetting = ti.GetPlatformTextureSettings("Android");
var piPSetting = ti.GetPlatformTextureSettings("iPhone");
var tex = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
bool pot = Mathf.IsPowerOfTwo(tex.width) && Mathf.IsPowerOfTwo(tex.height);
SettingPlantformTex(ti, pAndSetting, useCrunched,pot);
ti.SetPlatformTextureSettings(pAndSetting);
SettingPlantformTex(ti, piPSetting, useCrunched, pot);
ti.SetPlatformTextureSettings(piPSetting);
AssetDatabase.WriteImportSettingsIfDirty(path);
}
}
public class TextureSizeOptTool
{
[MenuItem("Tools/图片优化/优化选中文件夹中的图片-ASTC", priority = 1)]
public static void OnMenuItem_ASTC()
{
OptUITexSelectTex(false);
}
[MenuItem("Tools/图片优化/优化选中文件夹中的图片-Crunched", priority = 2)]
public static void OnMenuItem_Crunched()
{
OptUITexSelectTex(true);
}
public static void OptUITexSelectTex(bool useCrunched)
{
var guids = Selection.assetGUIDs;
var filePaths = new List<string>();
foreach (var id in guids)
{
var path = AssetDatabase.GUIDToAssetPath(id);
//可判断文件是否存在
if (File.Exists(path))
{
if (!filePaths.Contains(path))
filePaths.Add(path);
} //可判断文件路径是否存在
else if (Directory.Exists(path))
{
var subFileGuids = AssetDatabase.FindAssets("t:Texture", new string[] { path });
if (subFileGuids != null && subFileGuids.Length > 0)
{
foreach (var subId in subFileGuids)
{
var subPath = AssetDatabase.GUIDToAssetPath(subId);
if (!filePaths.Contains(subPath))
filePaths.Add(subPath);
}
}
}
}
if (filePaths.Count < 1) return;
for (int i = 0; i < filePaths.Count; i++)
{
string path = filePaths[i];
EditorUtility.DisplayProgressBar(
string.Format("Opt UI Texture({0}/{1})", i, filePaths.Count)
, path
, i * 1f / filePaths.Count
);
TextureSizeOptUtilities.ExtendTexture( path);
TextureSizeOptUtilities.SetTextureFormat(path, useCrunched);
}
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
EditorUtility.ClearProgressBar();
}
[MenuItem("Tools/图片优化/检查ManagedResources中所有图片格式", priority = 0)]
public static void OnMenuItem_Check()
{
var guid = AssetDatabase.FindAssets("t:Texture", new string[] { "Assets/ManagedResources" });
List<string> floders = new List<string>();
int errorTexCount = 0;
for (int i = 0; i < guid.Length; i++)
{
string id = guid[i];
var path = AssetDatabase.GUIDToAssetPath(id);
if (
path.StartsWith("Assets/ManagedResources/Atlas")
) continue;
EditorUtility.DisplayProgressBar(
string.Format("Check Texture({0}/{1})", i, guid.Length)
, path
, i * 1f / guid.Length
);
var floder = Path.GetDirectoryName(path);
var ti = AssetImporter.GetAtPath(path) as TextureImporter;
if (ti == null)
{
//Debug.LogError("No TextureImporter:" + path);
continue;
}
var tex = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
var pAndSetting = ti.GetPlatformTextureSettings("Android");
var piPSetting = ti.GetPlatformTextureSettings("iPhone");
if (!pAndSetting.overridden || !piPSetting.overridden)
{
if (!floders.Contains(floder)) floders.Add(floder);
++errorTexCount;
continue;
}
if (pAndSetting.format < TextureImporterFormat.ASTC_RGB_4x4 || piPSetting.format < TextureImporterFormat.ASTC_RGB_4x4)
{
if (!floders.Contains(floder)) floders.Add(floder);
++errorTexCount;
continue;
}
if (tex.width % 4 != 0 || tex.height % 4 != 0)
{
if (!floders.Contains(floder)) floders.Add(floder);
++errorTexCount;
continue;
}
}
if (floders.Count > 0)
{
Debug.Log("Error Tex Count:" + errorTexCount);
StringBuilder sb = new StringBuilder();
foreach (var f in floders)
{
sb.AppendLine(f);
}
Debug.Log(sb.ToString());
}
EditorUtility.ClearProgressBar();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b0b25c9e7b8af7f49a106f68f3d14da5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: