我们经常会遇到内存问题,这次就是遇到很多图片的默认格式被改成了RGB32,导致Android打包后运行内存明显增加。
发生了什么
打包Android后,发现经常崩溃,明显内存可能除了问题,看了内存后发现了问题。
见下图:
实际被改成了RGBA 32,如下图
因为安卓端是没覆写的,所以导致格式就是rgb32
如何处理
那么如何处理能,最好一键处理。我是这样做的,我对我的需要打包的预设,例如场景,角色等等资源批量检测他们中间引用了哪些图片,然后对这些图片进行处理,因为很多图片是过度文件不打包,进行处理也没必要,白白浪费时间。
代码片段,这里的cfg.path是需要打包prefab的路径,这里只有代码片段是因为我的打包逻辑是自己写的,篇幅问题只能放上核心代码。
代码如下:
string[] file = AssetDatabase.GetDependencies(cfg.path, true);
foreach (var dep in file)
{
string strExt = System.IO.Path.GetExtension(dep).ToLower();
if (!exps.Contains(strExt))
continue;
TextureImporter textureImporter = AssetImporter.GetAtPath(dep) as TextureImporter;
TextureImporterPlatformSettings set = textureImporter.GetDefaultPlatformTextureSettings();// .GetPlatformTextureSettings(path);
if (set.format != TextureImporterFormat.Automatic)
{
if (changeFormatAuto)
{
set.format = TextureImporterFormat.Automatic;
textureImporter.SetPlatformTextureSettings(set);
//EditorUtility.SetDirty(textureImporter);
// 重新导入资源,否则更改并未生效。
// 如资源未执行重新导入,则会在项目保存时自动导入、生效
AssetDatabase.ImportAsset(dep);
Debug.Log("修改预设" + cfg.prefabname + "中的图片资源格式存在的隐患:" + dep, textureImporter);
checkok = false;
allcount++;
}
else
{
Debug.LogError("预设" + cfg.prefabname + "中的图片资源格式存在隐患:" + dep, textureImporter);
allcount++;
checkok = false;
}
continue;
}
}
cfg.path就是perfab所在的位置。传入就可以了
脚本会自动改为Automatic格式。
最后再观察内存,图片找不到了,我放了其他的同尺寸图和一张4k的图,ASTC格式的2k大概是4.8M,4k只有19m内存。
最后希望大家有一个干净的资源包。
缩小纹理
可能PC转Android的时候,还希望能缩小纹理尺寸,可以利用这个对图片这样来处理。
//把图片的质量对半砍掉,0表示不砍掉,1:砍一半,2:1/4
public static bool CutHalfPicture(int sizeLevel = 1)
{
List<string> exps = new List<string>()
{ ".bmp",".jpg",".jpeg",".png",".tif",".psd",".tga"};
bool checkok = true;
int[] textureSizes = new int[] {
32,
64,
128,
256,
512,
1024,
2048,
4096,
8192,
16384,
};
int allcount = 0;
if (ResJsonObjectList == null || ResJsonObjectList.Count == 0)
JResAssetJson.ReadResJson();
for (int i = 0; i < ResJsonObjectList.Count; i++)
{
ResJson cfg = ResJsonObjectList[i];
if (cfg.isab != 1)
continue;
string[] file = AssetDatabase.GetDependencies(cfg.path, true);
foreach (var dep in file)
{
string strExt = System.IO.Path.GetExtension(dep).ToLower();
if (!exps.Contains(strExt))
continue;
TextureImporter textureImporter = AssetImporter.GetAtPath(dep) as TextureImporter;
TextureImporterPlatformSettings set = textureImporter.GetDefaultPlatformTextureSettings();// .GetPlatformTextureSettings(path);
//Debug.Log(set.maxTextureSize+",");
int width, height, max;
Texture2D tex = AssetDatabase.LoadAssetAtPath(dep, typeof(Texture2D)) as Texture2D;
width = tex.width; height = tex.height;
max = Mathf.Max(width, height);
int size = 32; //Default size
for (int j = 0; j < textureSizes.Length; j++)
{
if (textureSizes[j] >= max)
{
size = textureSizes[j];
break;
}
}
//set.maxTextureSize = 16384;
//Debug.Log(size);
size = (int)(size / Mathf.Pow(2, sizeLevel));
if (size < 32)
size = 32;
if (set.maxTextureSize != size)
{
set.maxTextureSize = size;
textureImporter.SetPlatformTextureSettings(set);
AssetDatabase.ImportAsset(dep);
Debug.Log("修改预设" + cfg.prefabname + "中的图片:" + dep + " ,大小:" + set.maxTextureSize, textureImporter);
checkok = false;
allcount++;
}
continue;
}
}
Debug.Log("累计共修改" + allcount + "处图片。");
return checkok;
}
代码中的ResJsonObjectList和JResAssetJson.ReadResJson()是预设列表和获取预设列表的方法,还是篇幅问题,这里无法放出。可以搜一下如何获取所有预设(prefab)的文章。
如果对你有用,请点赞。