using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.UI;
using System.Security.Cryptography;
using System.Text;
using System;
public struct ImageInfo
{
public string path { get; private set; }
public string md5 { get; set; }
public static string md5file(string file)
{
try
{
byte[] retVal = null;
using (FileStream fs = File.OpenRead(file))
{
MD5 md5 = new MD5CryptoServiceProvider();
retVal = md5.ComputeHash(fs);
}
System.Text.StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
catch (Exception ex)
{
throw new Exception("md5file() fail, error:" + ex.Message);
}
}
public ImageInfo(string path)
{
this.path = path;
this.md5 = md5file(this.path);
}
public bool CompareMd5(ImageInfo info)
{
return CompareMd5(info.md5);
}
public bool CompareMd5(string md5)
{
return this.md5 == md5;
}
}
public class ImageChecker : EditorWindow
{
public static readonly string[] ext = new string[] { ".png", ".jpg", ".psd" };
public static readonly string[] filters = new string[] { "IGSoft_Resources", "res" };
private string folderPath;
private string okFolderPath;
private string[][] results;
private string fixPath;
private Vector2 logScrollPos;
private string fix_name = "";
private Sprite[][] preImage;
public static string[][] CheckImage(string folderPath)
{
folderPath = string.IsNullOrEmpty(folderPath) ? Application.dataPath : folderPath;
string[] files = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories)
.Where(s =>
{
if (!ext.Contains(Path.GetExtension(s).ToLower()))
{
return false;
}
for (int i = 0; i < filters.Length; i++)
{
if (s.Contains(filters[i]))
{
return false;
}
}
return true;
}).ToArray();
ImageInfo[] infos = new ImageInfo[files.Length];
for (int i = 0; i < files.Length; i++)
{
infos[i] = new ImageInfo(FormatPath(files[i]));
}
Dictionary> dic = new Dictionary>();
for (int i = 0; i < infos.Length; i++)
{
ImageInfo info = infos[i];
if (!dic.ContainsKey(info.md5))
{
dic.Add(info.md5, new List());
}
dic[info.md5].Add(GetRelativePath(info.path));
}
string[] keys = dic.Keys.ToArray();
foreach (var key in keys)
{
if (dic[key].Count <= 1)
{
dic.Remove(key);
}
}
var values = dic.Values.ToArray();
string[][] result = new string[values.Length][];
for (int i = 0; i < values.Length; i++)
{
result[i] = values[i].ToArray();
}
return result;
}
[MenuItem("Tools/检测相同的image")]
public static void WindowCreator()
{
GetWindow(typeof(ImageChecker)).Show();
}
public void OnGUI()
{
EditorGUILayout.BeginVertical();
if (GUILayout.Button("选择文件夹"))
{
folderPath = EditorUtility.OpenFolderPanel("选择文件夹", folderPath, "");
}
GUILayout.Label("文件夹路径:" + folderPath);
if (GUILayout.Button("开始检测"))
{
results = CheckImage(folderPath);
}
GUILayout.Label("");
GUILayout.Label("一键修改全部");
if (GUILayout.Button("选择一键修改全部的目标文件夹"))
{
okFolderPath = EditorUtility.OpenFolderPanel("选择文件夹", okFolderPath, "");
}
GUILayout.Label("目标文件夹:" + okFolderPath);
if (GUILayout.Button("一键修改全部"))
{
if (results != null && results.Length > 0)
{
for (int i = 0; i < results.Length; i++)
{
string[] result = results[i];
preImage[i] = new Sprite[result.Length];
for (int j = 0; j < result.Length; j++)
{
fix_name = "fix_" + Path.GetFileNameWithoutExtension(result[j]);
EditorGUILayout.SelectableLabel(result[j], GUILayout.MaxHeight(18));
preImage[i][j] = AssetDatabase.LoadAssetAtPath(result[j]);
preImage[i][j] = (Sprite)EditorGUILayout.ObjectField(preImage[i][j], typeof(Sprite), true, GUILayout.Width(120));
}
string fullpath = okFolderPath + "/" + fix_name + ".png";
for (int j = 1; j < result.Length; j++)
{
Debug.unityLogger.Log("path:" + result[j], "checkPath:" + folderPath);
ChangeImageInFolder(folderPath, preImage[i][j], preImage[i][0]);
File.Delete(result[j]);
File.Delete(result[j] + ".meta");
}
File.Move(result[0], fullpath);
File.Move(result[0] + ".meta", fullpath + ".meta");
}
}
Debug.Log("一键修改全部完成");
}
ShowInfo();
EditorGUILayout.EndVertical();
}
private void ShowInfo()
{
if (results != null && results.Length > 0)
{
GUILayout.Label("查找结果为:");
logScrollPos = GUILayout.BeginScrollView(logScrollPos);
preImage = new Sprite[results.Length][];
for (int i = 0; i < results.Length; i++)
{
string[] result = results[i];
preImage[i] = new Sprite[result.Length];
for (int j = 0; j < result.Length; j++)
{
EditorGUILayout.SelectableLabel(result[j], GUILayout.MaxHeight(18));
preImage[i][j] = AssetDatabase.LoadAssetAtPath(result[j]);
preImage[i][j] = (Sprite)EditorGUILayout.ObjectField(preImage[i][j], typeof(Sprite), true, GUILayout.Width(120));
}
if (GUILayout.Button("修改到文件夹"))
{
fixPath = EditorUtility.OpenFolderPanel("修改到文件夹", fixPath, "");
}
GUILayout.Label("目标文件夹:" + fixPath);
fix_name = GUILayout.TextArea(fix_name, 20);
if (GUILayout.Button("修改"))
{
string fullpath = fixPath + "/" + fix_name + ".png";
for (int j = 1; j < result.Length; j++)
{
Debug.unityLogger.Log("path:" + result[j], "checkPath:" + folderPath);
ChangeImageInFolder(folderPath, preImage[i][j], preImage[i][0]);
File.Delete(result[j]);
File.Delete(result[j] + ".meta");
}
File.Move(result[0], fullpath);
File.Move(result[0] + ".meta", fullpath + ".meta");
}
GUILayout.Space(20);
GUILayout.Space(20);
}
GUILayout.EndScrollView();
}
else
{
GUILayout.Label("该路径下没有内容重复的图片!!!");
}
}
public void ChangeImageInFolder(string folderPath, Sprite preImage, Sprite targetImage)
{
if (!Directory.Exists(folderPath)) return;
string[] files = Directory.GetFiles(folderPath, "*.prefab", SearchOption.AllDirectories);
foreach (string f in files)
{
string file = FileUtil.GetProjectRelativePath(f).Replace("\\", "/");
GameObject obj = AssetDatabase.LoadAssetAtPath(file, typeof(GameObject)) as GameObject;
if (obj)
{
ChangeImage(obj, preImage, targetImage);
}
}
}
public void ChangeImage(GameObject obj, Sprite preImage, Sprite targetImage)
{
Image[] list = obj.GetComponentsInChildren();
string preImgPath = AssetDatabase.GetAssetPath(preImage);
string preImgGuid = AssetDatabase.AssetPathToGUID(preImgPath);
string curImgGuid;
bool isChange = false;
foreach (Image m in list)
{
curImgGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m.sprite));
if (preImgGuid == curImgGuid)
{
m.sprite = targetImage;
isChange = true;
}
}
EditorUtility.SetDirty(obj);
PrefabUtility.SetPropertyModifications(obj, new PropertyModification[0]);
//PrefabUtility.SetPropertyModifications(obj, PrefabUtility.GetPropertyModifications(obj));
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
if (isChange)
Debug.Log("*********成功替换:::" + obj.name);
}
public static string GetProjectRelativePath(string path)
{
return FormatPath(FileUtil.GetProjectRelativePath(path));
}
public static string FormatPath(string path)
{
return path.Replace("\\", "/");
}
public static string GetRelativePath(string path)
{
return CombinePath("Assets", Path.GetFullPath(path).Replace(Path.GetFullPath(Application.dataPath), ""));
}
public static string CombinePath(params string[] args)
{
for (int i = 0; i < args.Length; i++)
{
args[i] = args[i].Replace("\\", "/");
}
switch (args.Length)
{
case 0:
return string.Empty;
case 1:
return args[0];
default:
StringBuilder sb = new StringBuilder();
sb.Append(args[0]);
for (int i = 1; i < args.Length; i++)
{
if (args[i - 1].EndsWith("/"))
{
sb.Remove(sb.Length - 1, 1);
}
sb.AppendFormat(args[i].StartsWith("/") ? "{0}" : "/{0}", args[i]);
}
return sb.ToString();
}
}
}
点击Tools/检测相同的Image会弹出这个界面
选择文件夹扫描后
可以根据需要来对图片资源进行处理