質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.61%

【Unity】Unity上でのテクスチャファイルサイズを取得したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,926

score 616

実現したいこと

UnityでテクスチャのMaxSizeを変更すると、Inspectorの下側にUnity上でのテクスチャファイルサイズが表示されますが、これをスクリプトで取得できないかなと思っています。
イメージ説明

試したこと

        Texture ThisTex = Objects[0].GetComponent<Renderer>().material.mainTexture;
        string TexPath = AssetDatabase.GetAssetPath(ThisTex);
        FileInfo fileInfo = new FileInfo(TexPath);
        Debug.Log(fileInfo.Length);


こんな感じで取得できないかな~と試してみましたが、出てきた数字はテクスチャの元々のファイルサイズでした。
もし取得できないのであれば諦めます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

あそこの文字列はEditor.GetInfoStringをオーバーライドして表示しているようです。実装を見てみますと、たとえばTextureInspectorの場合はTextureUtilクラスのGetStorageMemorySizeLongRenderTextureEditorの場合はGetRuntimeMemorySizeLongを使ってサイズを取得しているようでした。
残念ながらTextureUtilinternalクラスのようですので、これらを使うとしたら下記のようなヘルパークラスを作って無理やりアクセスすることになると思います。

using System;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public static class TextureUtility
{
    private static Type textureUtilType;
    private static MethodInfo getStorageMemorySizeLongInfo;
    private static MethodInfo getRuntimeMemorySizeLongInfo;
    private static readonly Texture[] TextureArgument = new Texture[1];

    private static Type TextureUtilType
    {
        get
        {
            // TextureUtilクラスを探す
            if (textureUtilType == null)
            {
                textureUtilType = typeof(EditorApplication).Assembly.GetTypes().FirstOrDefault(t => t.FullName == "UnityEditor.TextureUtil");
                if (textureUtilType == null)
                {
                    throw new Exception("TextureUtil not found.");
                }
            }

            return textureUtilType;
        }
    }

    private static MethodInfo GetStorageMemorySizeLongInfo
    {
        get
        {
            // GetStorageMemorySizeLongを探す
            if (getStorageMemorySizeLongInfo == null)
            {
                getStorageMemorySizeLongInfo = TextureUtilType.GetMethod("GetStorageMemorySizeLong");
                if (getStorageMemorySizeLongInfo == null)
                {
                    throw new Exception("GetStorageMemorySizeLong not found.");
                }
            }

            return getStorageMemorySizeLongInfo;
        }
    }

    private static MethodInfo GetRuntimeMemorySizeLongInfo
    {
        get
        {
            // GetRuntimeMemorySizeLongを探す
            if (getRuntimeMemorySizeLongInfo == null)
            {
                getRuntimeMemorySizeLongInfo = TextureUtilType.GetMethod("GetRuntimeMemorySizeLong");
                if (getRuntimeMemorySizeLongInfo == null)
                {
                    throw new Exception("GetRuntimeMemorySizeLong not found.");
                }
            }

            return getRuntimeMemorySizeLongInfo;
        }
    }

    // テクスチャデータのバイト数を得る(メインメモリ側に保持されているデータのサイズ?)
    public static long GetStorageMemorySizeLong(Texture texture)
    {
        TextureArgument[0] = texture;
        return (long)GetStorageMemorySizeLongInfo.Invoke(null, TextureArgument);
    }

    // テクスチャデータのバイト数を得る(グラフィックメモリ側に保持されているデータのサイズ?)
    public static long GetRuntimeMemorySizeLong(Texture texture)
    {
        TextureArgument[0] = texture;
        return (long)GetRuntimeMemorySizeLongInfo.Invoke(null, TextureArgument);
    }
}

他にもProfiler.GetRuntimeMemorySizeLongなんてものもあるようで、こちらはUnityユーザー側も使えるように公開されているみたいですね。リファレンスのサンプルコードに、まさにこれを使ってテクスチャのサイズを調べる例が載っていました。

Texture2DRenderTextureを使っていくつか試してみたところ、Profiler.GetRuntimeMemorySizeLongの値とTextureUtil.GetRuntimeMemorySizeLongの値はいつも一致しているように思われました。RenderTextureについてはProfiler.GetRuntimeMemorySizeLongを使えばよさそうです。

Texture2Dの場合、たまにTextureUtil.GetStorageMemorySizeLongTextureUtil.GetRuntimeMemorySizeLongの値が異なるケースがあるようです。詳しく調べておりませんので不確かですが、幅か高さが極端に小さい(4ピクセル未満?)とか、圧縮フォーマットであるとか、サイズが2の冪乗でないとかが関係しているような気もします。
インスペクターに表示されるのはTextureUtil.GetStorageMemorySizeLongの方で、Profiler.GetRuntimeMemorySizeLongで取得されるのはTextureUtil.GetRuntimeMemorySizeLongの方みたいですから、Texture2Dに関してはTextureUtil.GetStorageMemorySizeLongを使った方がつじつまの合った値が得られそうです。

他にも、Texture2DならGetRawTextureDataでテクスチャデータを取ってきて、それのバイト数を調べるという手が使えるかもしれません。

        public static long GetRawDataSize(Texture2D texture)
        {
            return texture.GetRawTextureData().LongLength;
        }

いくつか試したかぎりではTextureUtil.GetStorageMemorySizeLongの方の値と一致しているようでした。サイズを調べるためだけにテクスチャデータ全体を取得するというのはちょっと大げさな気がしますが、TextureUtilに頼らずやりたいなら仕方ないかもしれませんね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/13 08:47

    詳細かつ丁寧な解説付きの回答ありがとうございます。
    すごい知識量ですね..、なるほど、一応は取得方法はあるんですね。
    実際にTextureUtil.GetStorageMemorySizeLongを使って取得してみようと思います、回答ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る