C#
Unity

ファイルパスからTexture2DやSpriteの読み込み

More than 1 year has passed since last update.

UnityをScriptでゴニョゴニョやってるとSpriteやTexture2Dをパスから読み込んで…みたいなのがたくさんあったのでメソッド化してみた。
シングルトンのクラスにいれてやるとキャッシュなどもでき結構楽になりました。

ファイルパスからTexture2D読み込み

引数のファイルパスからbyteでデータ読み込み、Texture2Dへの変換を行っています。

Texture2DFromFile
public Texture2D Texture2DFromFile(string path)
{
    Texture2D texture = null;
    if (File.Exists(path))
    {
        //byte取得
        FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
        BinaryReader bin = new BinaryReader(fileStream);
        byte[] readBinary = bin.ReadBytes((int)bin.BaseStream.Length);
        bin.Close();
        fileStream.Dispose();
        fileStream = null;
        if (readBinary != null)
        {
            //横サイズ
            int pos = 16;
            int width = 0;
            for (int i = 0; i < 4; i++)
            {
                width = width * 256 + readBinary[pos++];
            }
            //縦サイズ
            int height = 0;
            for (int i = 0; i < 4; i++)
            {
                height = height * 256 + readBinary[pos++];
            }
            //byteからTexture2D作成
            texture = new Texture2D(width, height);
            texture.LoadImage(readBinary);
        }
        readBinary = null;
    }
    return texture;
}

ファイルパスからSprite読み込み

※Assets>Resoucesフォルダ内の画像であればResources.Load<Sprite>("ファイルパス");でも取得できます。

まず、Texture2DからSpriteへ変換するメソッドです。

SpriteFromTexture2D
public Sprite SpriteFromTexture2D(Texture2D texture)
{
    Sprite sprite = null;
    if (texture)
    {
        //Texture2DからSprite作成
        sprite = Sprite.Create(texture, new UnityEngine.Rect(0, 0, texture.width, texture.height), Vector2.zero);
    }
    return sprite;
}

ファイルからSpriteへの変換は
Texture2DFromFileでファイルからTexture2D読み込み
SpriteFromTexture2Dで読み込んだTexture2DをSpriteに変換しています。

SpriteFromFile
public Sprite SpriteFromFile(string path)
{
    Sprite sprite = null;
    Texture2D texture = Texture2DFromFile(path);
    if (texture)
    {
        //Texture2DからSprite作成
        sprite = SpriteFromTexture2D(texture);
    }
    texture = null;
    return sprite;
}

応用として

フォルダパスからファイル一覧を取得できるのでフォルダ内のpng画像をSpriteのListとして取得するメソッドなども用意しました。

枚数によってはかなり重いのでフォルダパスに紐付けてキャッシュするように修正しました。
bool cacheがfalseの時、またはキャッシュに保存していないときは新規取得になります。
このメソッドをシングルトンのクラスに配置することで一度取得した画像のリストを高速で取得することができます。

SpriteListFromFolder
Dictionary<string, List<Sprite>> spriteListCache = new Dictionary<string, List<Sprite>>();
public List<Sprite> SpriteListFromFolder(string path, bool cache)
{
    List<Sprite> images = null;
    if (cache)
    {
        //キャッシュしているか判定
        if (spriteListCache.ContainsKey(path))
        {
            //キャッシュから読み込み
            images = spriteListCache[path];
        }
    }
    if (images == null)
    {
        //新規読み込み
        images = new List<Sprite>();
        if (Directory.Exists(path))
        {
            //フォルダ内のpngファイルのファイル名取得
            DirectoryInfo dir = new DirectoryInfo(path);
            FileInfo[] info = dir.GetFiles("*.png");
            foreach (FileInfo file in info)
            {
                string filePath = path + file.Name;
                //ファイルパスからpng読み込み
                Sprite sprite = SpriteFromFile(filePath);
                if (sprite)
                {
                    images.Add(sprite);
                }
                sprite = null;
            }
            info = null;
            dir = null;
        }
        //読み込み結果をキャッシュへ保存
        spriteListCache.Add(path, images);
    }
    return images;
}