【unity】批量剔除图片四周空白像素的工具

发布于:2025-06-22 ⋅ 阅读:(19) ⋅ 点赞:(0)

摘要:Unity图片空白像素批量处理工具
该工具提供两种方式批量剔除图片空白像素:

静态处理类:提供TrimTexture方法,可读取纹理像素数据,计算非透明区域边界,生成裁剪后的新纹理;SaveTexture方法保存处理结果。
编辑器窗口:通过"Tools/UI"菜单打开窗口,支持多选PNG图片后批量处理。主要流程包括:加载选中项→分析像素边界→裁剪保存→恢复原始设置。处理时临时修改纹理为可读状态,完成后自动刷新资源库并统计成功数量。适用于UI图片资源优化,需在Unity编辑器环境下使用。

using UnityEditor;
using UnityEngine;
using System.IO;

public static class ImageTrimmerHandle
{
    public static Texture2D TrimTexture(Texture2D sourceTexture)
    {
        if (sourceTexture == null) return null;

        string assetPath = AssetDatabase.GetAssetPath(sourceTexture);
        TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;

        if (importer == null) return null;

        bool originalReadable = importer.isReadable;
        TextureImporterCompression originalCompression = importer.textureCompression;

        // 设置为可读
        importer.isReadable = true;
        importer.textureCompression = TextureImporterCompression.Uncompressed;
        AssetDatabase.ImportAsset(assetPath);
        AssetDatabase.Refresh();

        // 重新加载纹理
        Texture2D readableTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
        Color[] pixels = readableTexture.GetPixels();

        // 找到边界
        int width = readableTexture.width;
        int height = readableTexture.height;
        int left = width;
        int right = 0;
        int top = 0;
        int bottom = height;

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                Color pixel = pixels[y * width + x];
                if (pixel.a > 0.01f) // 非完全透明
                {
                    left = Mathf.Min(left, x);
                    right = Mathf.Max(right, x);
                    top = Mathf.Max(top, y);
                    bottom = Mathf.Min(bottom, y);
                }
            }
        }

        // 创建新纹理
        int newWidth = right - left + 1;
        int newHeight = top - bottom + 1;

        Texture2D trimmedTexture = null;

        if (newWidth > 0 && newHeight > 0)
        {
            trimmedTexture = new Texture2D(newWidth, newHeight, TextureFormat.RGBA32, false);
            Color[] newPixels = new Color[newWidth * newHeight];

            for (int y = bottom; y <= top; y++)
            {
                for (int x = left; x <= right; x++)
                {
                    int sourceIndex = y * width + x;
                    int destIndex = (y - bottom) * newWidth + (x - left);
                    newPixels[destIndex] = pixels[sourceIndex];
                }
            }

            trimmedTexture.SetPixels(newPixels);
            trimmedTexture.Apply();
        }

        // 恢复原始导入设置
        importer.isReadable = originalReadable;
        importer.textureCompression = originalCompression;
        AssetDatabase.ImportAsset(assetPath);

        return trimmedTexture;
    }

    public static void SaveTexture(Texture2D texture, string savePath)
    {
        if (texture == null || string.IsNullOrEmpty(savePath)) return;

        byte[] bytes = texture.EncodeToPNG();
        string directory = Path.GetDirectoryName(savePath);

        if (!Directory.Exists(directory))
        {
            Directory.CreateDirectory(directory);
        }

        File.WriteAllBytes(savePath, bytes);
        AssetDatabase.Refresh();

        Debug.Log("图片已保存至: " + savePath);

        // 自动选择保存的资源
        Texture2D savedTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(savePath);
        if (savedTexture != null)
        {
            Selection.activeObject = savedTexture;
        }
    }
}
using UnityEditor;
using UnityEngine;
using System.IO;

public class ImageTrimmerWindow : EditorWindow
{
    private Object[] selectedTextures;

    [MenuItem("Tools/UI/批量剔除图片的空白像素")]
    public static void ShowWindow()
    {
        GetWindow<ImageTrimmerWindow>("批量剔除图片的空白像素");
    }

    private void OnGUI()
    {
        GUILayout.Label("批量图片空白像素剔除", EditorStyles.boldLabel);
        EditorGUILayout.Space();

        EditorGUILayout.HelpBox("请选择一个或多个 PNG 图片文件(可在Project窗口多选后点击“从选中项加载”)。", MessageType.Info);

        if (GUILayout.Button("从选中项加载"))
        {
            selectedTextures = Selection.GetFiltered(typeof(Texture2D), SelectionMode.Assets);
        }

        if (selectedTextures != null && selectedTextures.Length > 0)
        {
            EditorGUILayout.LabelField($"已选择图片数量: {selectedTextures.Length}");

            if (GUILayout.Button("批量剔除并覆盖保存"))
            {
                int successCount = 0;
                foreach (Object obj in selectedTextures)
                {
                    Texture2D tex = obj as Texture2D;
                    if (tex == null) continue;

                    Texture2D trimmed = ImageTrimmerHandle.TrimTexture(tex);
                    if (trimmed != null)
                    {
                        string path = AssetDatabase.GetAssetPath(tex);
                        ImageTrimmerHandle.SaveTexture(trimmed, path);
                        successCount++;
                    }
                }
                AssetDatabase.Refresh();
                EditorUtility.DisplayDialog("处理完成", $"已处理并覆盖保存 {successCount} 张图片。", "确定");
            }
        }
        else
        {
            EditorGUILayout.LabelField("未选择图片。");
        }
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到