うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】テクスチャのある色を透過するツール

テクスチャの透過変換を他のサイト等で行うのが面倒だったので
もしや Unity でできるのではと思い作成してみました

f:id:hacchi_man:20201020020727p:plain:w200

変換サンプル

例えばいらすとやさんの画像を肌色っぽいところを閾値0.1で透過に変換すると

f:id:hacchi_man:20201021005129p:plain:w200

このように変換できます

f:id:hacchi_man:20201021005436p:plain:w300

コード

using UnityEditor;
using UnityEngine;
 
public class TextureAlphaConvertWindow : EditorWindow
{
    [MenuItem("Tools/TextureEdit")]
    private static void ShowWindow()
    {
        var window = GetWindow<TextureAlphaConvertWindow>();
        window.Show();
    }
  
    private Texture2D _texture;
    private Color _targetColor;
    private float _thresholdColor;
 
    private void OnGUI()
    {
        _texture = (Texture2D) EditorGUILayout.ObjectField("Target Texture", _texture, typeof(Texture2D));
        _targetColor = EditorGUILayout.ColorField("Target", _targetColor);
        _thresholdColor = EditorGUILayout.Slider("Color threshold", _thresholdColor, 0f, 1f);
        using (new EditorGUI.DisabledScope(_texture == null))
        {
            if (GUILayout.Button("Transport"))
            {
                ColorToAlpha(_texture, _targetColor, _thresholdColor);
            }
        }
    }
 
    private static void ColorToAlpha(Texture2D src, Color targetColor, float thresholdColor)
    {
        var texture = new Texture2D(src.width, src.height, src.format, src.mipmapCount == -1);
        var path = AssetDatabase.GetAssetPath(src);
        var importer = AssetImporter.GetAtPath(path) as TextureImporter;
 
        var isChange = !importer.isReadable;
        if (isChange)
        {
            importer.isReadable = true;
            importer.SaveAndReimport();
            AssetDatabase.Refresh();
        }
 
        // 全ピクセルをコピー
        for (var x = 0; x < src.width; x++)
        {
            for (var y = 0; y < src.height; y++)
            {
                var color = src.GetPixel(x, y);
                var isReplace = true;
                for (var i = 0; i < 3; i++)
                {
                    if (!(color[i] >= targetColor[i] - thresholdColor) || !(color[i] <= targetColor[i] + thresholdColor))
                    {
                        isReplace = false;
                        break;
                    }
                }
 
                if (isReplace)
                    color.a = 0f;
 
                texture.SetPixel(x, y, color);
            }
        }
 
        texture.Apply();
 
        System.IO.File.WriteAllBytes(path.Replace('/', System.IO.Path.DirectorySeparatorChar), texture.EncodeToPNG());
        AssetDatabase.Refresh();
        if (isChange)
        {
            var importer2 = AssetImporter.GetAtPath(path) as TextureImporter;
            importer2.isReadable = false;
            importer2.SaveAndReimport();
        }
    }
}