1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Unity】Gradientを画像として書き出すエディタ拡張

Posted at

UnityでGradientを画像にして書き出すエディタ拡張です。

ソースコードをEditorディレクトリ配下に配置すると、メニューのWindow/Gradient Exporterからウィンドウを開くことができるようになります。
以下のように設定して、Exportボタンを押すと、
GradientExporter.PNG

このような画像が書き出されます。

gradient.png

GradientExportWindow.cs
using System.IO;
using UnityEngine;
using UnityEditor;

namespace GradientExporter
{
    public enum AlphaExport
    {
        True,
        False,
        Selectable,
    }

    public enum GradientExportFormat
    {
        Png,
        Jpg,
        Tga,
        Exr
    }

    public static class GradientExportFormatExt
    {
        public static bool IsHdr(this GradientExportFormat format)
        {
            return format == GradientExportFormat.Exr;
        }

        public static AlphaExport GetAlphaExport(this GradientExportFormat format)
        {
            switch (format)
            {
                case GradientExportFormat.Png:
                case GradientExportFormat.Tga:
                    return AlphaExport.Selectable;
                case GradientExportFormat.Jpg:
                    return AlphaExport.False;
                case GradientExportFormat.Exr:
                    return AlphaExport.True;
                default:
                    throw new Exception("Unknown value of GradientExportFormat");
            }
        }

        public static TextureFormat GetTextureFormat(this GradientExportFormat format, bool alpha)
        {
            switch (format)
            {
                case GradientExportFormat.Png:
                case GradientExportFormat.Tga:
                    return alpha ? TextureFormat.ARGB32 : TextureFormat.RGB24;
                case GradientExportFormat.Jpg:
                    return TextureFormat.RGB24;
                case GradientExportFormat.Exr:
                    return TextureFormat.RGBAHalf;
                default:
                    throw new Exception("Unknown value of GradientExportFormat");
            }
        }

        public static byte[] Encode(this GradientExportFormat format, Texture2D texture)
        {
            switch (format)
            {
                case GradientExportFormat.Png:
                    return texture.EncodeToPNG();
                case GradientExportFormat.Jpg:
                    return texture.EncodeToJPG(100);
                case GradientExportFormat.Tga:
                    return texture.EncodeToTGA();
                case GradientExportFormat.Exr:
                    return texture.EncodeToEXR();
                default:
                    throw new Exception("Unknown value of GradientExportFormat");
            }
        }

        public static string GetExtension(this GradientExportFormat format)
        {
            switch (format)
            {
                case GradientExportFormat.Png:
                    return "png";
                case GradientExportFormat.Jpg:
                    return "jpg";
                case GradientExportFormat.Tga:
                    return "tga";
                case GradientExportFormat.Exr:
                    return "exr";
                default:
                    throw new Exception("Unknown value of GradientExportFormat");
            }
        }
    }

    public enum GradientExportDirection
    {
        LeftToRight,
        RightToLeft,
        BottomToTop,
        TopToBottom
    }

    public static class GradientExportDirectionExt
    {
        public static bool IsHorizontal(this GradientExportDirection direction)
        {
            return direction == GradientExportDirection.LeftToRight || direction == GradientExportDirection.RightToLeft;
        }

        public static bool IsInverted(this GradientExportDirection direction)
        {
            return direction == GradientExportDirection.RightToLeft || direction == GradientExportDirection.TopToBottom;
        }
    }

    public class GradientExportWindow : EditorWindow
    {
        Gradient gradient = new Gradient();
        Gradient hdrGradient = new Gradient();
        GradientExportFormat format = GradientExportFormat.Png;
        GradientExportDirection direction = GradientExportDirection.LeftToRight;
        bool alpha = false;
        int size = 256;

        [MenuItem("/Window/Gradient Exporter")]
        public static void CreateWindow()
        {
            GetWindow<GradientExportWindow>("Gradient Exporter");
        }

        void OnGUI()
        {
            var exportable = false;

            format = (GradientExportFormat) EditorGUILayout.EnumPopup("Format", format);
            if (format.IsHdr())
            {
                EditorGUILayout.GradientField(new GUIContent("Gradient"), hdrGradient, true);
            }
            else
            {
                EditorGUILayout.GradientField("Gradient", gradient);
            }

            size = EditorGUILayout.IntField("Image Size", size);
            if (size <= 0)
            {
                exportable = true;
                EditorGUILayout.HelpBox("Image size must be bigger than 0.", MessageType.Error);
            }

            direction = (GradientExportDirection) EditorGUILayout.EnumPopup("Image Direction", direction);

            var alphaExport = format.GetAlphaExport();
            using (new EditorGUI.DisabledGroupScope(alphaExport != AlphaExport.Selectable))
            {
                if (alphaExport == AlphaExport.True)
                {
                    alpha = true;
                }
                else if (alphaExport == AlphaExport.False)
                {
                    alpha = false;
                }
                alpha = EditorGUILayout.Toggle("Alpha", alpha);
            }

            using (new EditorGUI.DisabledGroupScope(exportable))
            {
                if (GUILayout.Button("Export"))
                {
                    var targetGradient = format.IsHdr() ? hdrGradient : gradient;
                    Export(targetGradient, format, alpha, size, direction);
                }
            }
        }

        static void Export(Gradient gradient, GradientExportFormat format, bool alpha, int size, GradientExportDirection direction)
        {
            var extension = format.GetExtension();
            var path = EditorUtility.SaveFilePanel("Export Gradient as Image", "", $"Gradient.{extension}", extension);
            if (path == "") return;

            var texture = CreateTexture(gradient, format.GetTextureFormat(alpha), size, direction);
            var binaries = format.Encode(texture);
            DestroyImmediate(texture);

            File.WriteAllBytes(path, binaries);
            AssetDatabase.Refresh();
        }

        static Texture2D CreateTexture(Gradient gradient, TextureFormat format, int size, GradientExportDirection direction)
        {

            var texture = direction.IsHorizontal() ? new Texture2D(size, 1, format, false): new Texture2D(1, size, format, false);
            var inverted = direction.IsInverted();
            var pixels = texture.GetPixels();
            for (var i = 0; i < pixels.Length; ++i)
            {
                var t = (float)i / (pixels.Length - 1);
                pixels[i] = gradient.Evaluate(inverted ? 1.0f - t : t);
            }
            texture.SetPixels(pixels);
            texture.Apply(false);
            return texture;
        }
    }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?