Created
August 14, 2025 05:02
-
-
Save aprius/87bbbbbcf1a820126d48035829ffc069 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using UnityEngine; | |
| using UnityEditor; | |
| using System.IO; | |
| using System.Linq; | |
| public static class ConvertAssetToPNG | |
| { | |
| // Chỉ hiện menu nếu có ít nhất 1 Texture2D hoặc Sprite được chọn | |
| [MenuItem("Assets/Convert to PNG", true)] | |
| private static bool ValidateConvert() | |
| { | |
| return Selection.objects.Any(o => o is Texture2D || o is Sprite); | |
| } | |
| [MenuItem("Assets/Convert to PNG")] | |
| private static void ConvertSelected() | |
| { | |
| var objs = Selection.objects.Where(o => o is Texture2D || o is Sprite).ToArray(); | |
| int success = 0, fail = 0; | |
| foreach (var obj in objs) | |
| { | |
| try | |
| { | |
| if (obj is Sprite s) | |
| ExportSpriteToPng(s); | |
| else if (obj is Texture2D t) | |
| ExportTextureToPng(t, obj.name, AssetDatabase.GetAssetPath(obj)); | |
| success++; | |
| } | |
| catch (System.Exception ex) | |
| { | |
| Debug.LogError($"[Convert to PNG] {obj.name}: {ex.Message}"); | |
| fail++; | |
| } | |
| } | |
| AssetDatabase.Refresh(); | |
| Debug.Log($"[Convert to PNG] Done. Success: {success}, Fail: {fail}"); | |
| } | |
| private static void ExportSpriteToPng(Sprite sprite) | |
| { | |
| var tex = sprite.texture; | |
| if (tex == null) throw new System.Exception("Sprite không có texture!"); | |
| // Kích thước ảnh xuất đúng theo rect của sprite | |
| int w = Mathf.RoundToInt(sprite.rect.width); | |
| int h = Mathf.RoundToInt(sprite.rect.height); | |
| // Blit full texture vào RT, rồi ReadPixels đúng vùng sprite.rect | |
| RenderTexture rt = RenderTexture.GetTemporary(tex.width, tex.height, 0, RenderTextureFormat.ARGB32); | |
| var prev = RenderTexture.active; | |
| try | |
| { | |
| Graphics.Blit(tex, rt); | |
| RenderTexture.active = rt; | |
| Texture2D readable = new Texture2D(w, h, TextureFormat.RGBA32, false); | |
| // Read vùng con theo rect của sprite (tọa độ pixel) | |
| Rect r = sprite.rect; | |
| readable.ReadPixels(new Rect(r.x, r.y, r.width, r.height), 0, 0, false); | |
| readable.Apply(false, false); | |
| string assetPath = AssetDatabase.GetAssetPath(sprite); | |
| string savePath = BuildSavePath(assetPath, sprite.name); | |
| WritePng(readable, savePath); | |
| } | |
| finally | |
| { | |
| RenderTexture.active = prev; | |
| RenderTexture.ReleaseTemporary(rt); | |
| } | |
| } | |
| private static void ExportTextureToPng(Texture2D tex, string name, string assetPath) | |
| { | |
| int w = tex.width, h = tex.height; | |
| // Blit để “bóc” khỏi GPU format (kể cả compressed) -> RGBA32 | |
| RenderTexture rt = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32); | |
| var prev = RenderTexture.active; | |
| try | |
| { | |
| Graphics.Blit(tex, rt); | |
| RenderTexture.active = rt; | |
| Texture2D readable = new Texture2D(w, h, TextureFormat.RGBA32, false); | |
| readable.ReadPixels(new Rect(0, 0, w, h), 0, 0, false); | |
| readable.Apply(false, false); | |
| string savePath = BuildSavePath(assetPath, name); | |
| WritePng(readable, savePath); | |
| } | |
| finally | |
| { | |
| RenderTexture.active = prev; | |
| RenderTexture.ReleaseTemporary(rt); | |
| } | |
| } | |
| private static string BuildSavePath(string assetPath, string baseName) | |
| { | |
| // Lưu cạnh file gốc | |
| string projectRelativeDir = Path.GetDirectoryName(assetPath) ?? "Assets"; | |
| string projectRelative = Path.Combine(projectRelativeDir, baseName + ".png").Replace('\\','/'); | |
| // Đổi sang đường dẫn hệ thống | |
| string absolute = Path.Combine(Application.dataPath, projectRelative.Substring("Assets/".Length)); | |
| string dir = Path.GetDirectoryName(absolute); | |
| if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); | |
| // Tránh trùng tên | |
| string finalPath = absolute; | |
| int i = 1; | |
| while (File.Exists(finalPath)) | |
| { | |
| finalPath = Path.Combine(dir, $"{baseName} ({i}).png"); | |
| i++; | |
| } | |
| return finalPath; | |
| } | |
| private static void WritePng(Texture2D tex, string absolutePath) | |
| { | |
| byte[] png = tex.EncodeToPNG(); | |
| if (png == null || png.Length == 0) throw new System.Exception("EncodeToPNG thất bại."); | |
| File.WriteAllBytes(absolutePath, png); | |
| Debug.Log($"[Convert to PNG] Saved: {absolutePath}"); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment