夜風のMixedReality

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

写真をテクスチャ2Dにキャプチャする

本日はHoloLensのキャプチャに関しての調査記事です。

前回写真の撮影までの流れを調査しました。

redhologerbera.hatenablog.com

簡単におさらいすると

①PhotoCaptureオブジェクトを作成する

②設定したいCameraParametersオブジェクトを作成します。

③StartPhotoModeAsync によるフォトモードの開始

④写真を撮る

⑤(オプション) 画像の追加の処理

フォトモードを停止しリソースをクリーンアップ

という流れで撮影の処理を行っていました。

スクリプトは次のようになります。

using UnityEngine;
using UnityEngine.Windows.WebCam;
using System.Linq;
using UnityEngine.XR;

public class PhotoCapturetest: MonoBehaviour
{
    PhotoCapture photoCaptureObject = null;
    void Start()
    {
        PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
    }
    void OnPhotoCaptureCreated(PhotoCapture captureObject)
    {
        photoCaptureObject = captureObject;

        Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();

        CameraParameters c = new CameraParameters();
        c.hologramOpacity = 0.0f;
        c.cameraResolutionWidth = cameraResolution.width;
        c.cameraResolutionHeight = cameraResolution.height;
        c.pixelFormat = CapturePixelFormat.BGRA32;

        captureObject.StartPhotoModeAsync(c,OnPhotoModeStarted);
    }

    private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
    {
        if (result.success)
        {
            string filename = string.Format(@"CapturedImage{0}_n.jpg", Time.time);
            string filePath = System.IO.Path.Combine(Application.persistentDataPath, filename);

            photoCaptureObject.TakePhotoAsync(filePath, PhotoCaptureFileOutputFormat.JPG, OnCapturedPhotoToDisk);
        }
        else
        {
            Debug.LogError("Unable to start photo mode!");
        }
    }
    void OnCapturedPhotoToDisk(PhotoCapture.PhotoCaptureResult result)
    {
        if (result.success)
        {
            Debug.Log("Saved Photo to disk!");
            photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
        }
        else
        {
            Debug.Log("Failed to save Photo to disk");
        }
    }

    void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
    {
        photoCaptureObject.Dispose();
        photoCaptureObject = null;
    }
}

今回は写真をTexture2Dにします。

〇写真をテクスチャ2Dにキャプチャする

Texture2DとはUnity内で使用する画像を保存するデータの型です。

Texture2Dの方でキャプチャを行うことでその後Unityで扱える様々な処理を行えます。

docs.unity3d.com

〇フレームをメモリにキャプチャ

PhotoCapturetestのOnPhotoModeStarted()を次のように書き換えます。

private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
   {
       if (result.success)
       {
           photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
       }
       else
       {
           Debug.LogError("Unable to start photo mode!");
       }
   }

フォトキャプチャー操作の結果情報を格納したデータコンテナである[PhotoCapture.PhotoCaptureResult]の操作の完了を示す[success]が真の場合

 photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);

で撮影を行います。

昨日の撮影して保存する場合はファイル名、保存場所などなどを設定していましたが今回はTexture2Dとして用いるためいきなり撮影を行っています。

void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
   {
       if (result.success)
       {
           // Create our Texture2D for use and set the correct resolution
           Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
           Texture2D targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
           // Copy the raw image data into our target texture
           photoCaptureFrame.UploadImageDataToTexture(targetTexture);
           // Do as we wish with the texture such as apply it to a material, etc.
       }
       // Clean up
       photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
   }

targetTextureとして撮影時の解像度でTexture2Dを作成し、 photoCaptureFrame.UploadImageDataToTextureでコピーします。

PhotoCaptureFrame.UploadImageDataToTexture()はUnityで提供されている撮影した画像をテクスチャデータにコピーするメソッドです。

これでtargetTextureに画像がコピーされました。 ドキュメントではDo as we wish with the texture such as apply it to a material, etc.Materialに張り付けるなど好きに利用してください。 とあります。

この後はtargetTextureを通常のTexture2Dとして扱えるようです。

本日は以上です。