【unity】unity删除冗余的图片资源编辑器工具

 


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<string, List<string>> dic = new Dictionary<string, List<string>>();

        for (int i = 0; i < infos.Length; i++)
        {
            ImageInfo info = infos[i];
            if (!dic.ContainsKey(info.md5))
            {
                dic.Add(info.md5, new List<string>());
            }

            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<Sprite>(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<Sprite>(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<Image>();
        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会弹出这个界面

 选择文件夹扫描后

 可以根据需要来对图片资源进行处理

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值