夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

MixedRealityModelingTools その⑨ Unity上で受け取ったイメージデータを処理する

本日はMRMT枠です。

〇MRMTとは?

MixedRealityModelingToolsは筆者が開発しているBlenderのアドオンと、UnityやUE5などMixedRealityアプリケーション内で連携させることができるパッケージで構成されるソリューションです。

github.com

データ形式と判別

前回はBlenderからUnityに対してイメージデータを送信しました。

redhologerbera.hatenablog.com

今回はここで送信されてUnity側で受信したデータをもとにイメージデータにデコードしていきます。

Blender側では次のようなバイナリが送信されています。

\x83\xa6header\xa4IMGE\xa9imagename\xd9!istockphoto-610545962-170667a.jpg\xa9imagedata\xdb\x00\x01F\xac/9j/4AAQSkZJRgABAQEBLAEsAAD・・・f//Z

Headerとして埋め込んだIMGEによって画像データと識別させistockphoto-610545962-170667a.jpgで画像名、そして画像本体データを送信しています。

Unity側で受け取ったデータはヘッダー情報を読み解いて、そのデータに合わせてデシリアライズを実行しています。

        private void ProcessReceivedData(byte[] data, int length)
        {
            // Get the header from the received data
            string header = Encoding.ASCII.GetString(data, 9, 4);
            Debug.Log(header);
            if (header == "MESH")
            {
                // Mesh data received
              ・・・
            }
            else if (header == "MATE")
            {
            ・・・
            }
            else if (header == "IMGE")
            {
                Debug.Log("IMGE");
                var imageData = DeserializeImageData(data, length);
                _objectBuilder._ImageData = imageData;
                _objectBuilder._isGetImageData = true;
                Debug.Log($"Received image data: {imageData.imagename}");
            }
            else
            {
                Debug.Log($"Received unknown data with header: {header}");
            }
        }

イメージデータとして処理をする際のフォーマットは次のように定義しています。

これはBlender側でシリアライズするのと同様になっています。

   [DataContract]
    public class ImageData
    {
        [DataMember] public string header;
        
        [DataMember] public string imagename;
        
        [DataMember] public string imagedata; // Base64 encoded image data

        // Add a property to convert Base64 string to byte[]
        public byte[] ImageBytes => System.Convert.FromBase64String(imagedata);
        
    }

画像データ自体はBase64のバイトなので、string型で定義し実態としてImageBytesとしてコンバートしています。

〇データをテクスチャに変換するメソッド

今回はMRMTでオブジェクトを構築するObjectBuilderコンポーネントに次の関数を実装しています。

   public void CreateTexture()
        {
            Texture2D texture = new Texture2D(1, 1); // 仮のサイズを指定
            byte[] decodedBinaryData = _ImageData.ImageBytes;
            texture.LoadImage(decodedBinaryData); // バイト配列をTexture2Dに読み込む 
            texture.name = _ImageData.imagename;

            // テクスチャをミップマップを含まないように設定(オプション)
            texture.filterMode = FilterMode.Bilinear;
            texture.wrapMode = TextureWrapMode.Clamp;

            _debugMaterial.mainTexture = texture;
            _blenderTexture.Add(texture);

            if (_blenderMat.Count > 0)
            {
                //Debug
                _blenderMat[0].mainTexture = texture;
            }
        }

Unityではテクスチャを扱う場合Texture2D型を使用します。

初期化したTexture2Dにバイナリを読み込ませるためにはTexture2D.LoadImage()メソッドを使用します。

  texture.LoadImage(decodedBinaryData);

これによってUnity側で画像を取得することができました。

本日は以上です。