MRが楽しい

MRやVRについて学習したことを書き残す

HoloLensでカメラ画像を取得する その2(ファイルに写真を取り込む)

本日は Unity の技術調査枠です。
先日の資料を基に、キャプチャ画像をファイル出力するプロジェクトを作成します。
bluebirdofoz.hatenablog.com

前回ドキュメントに基づいて、ファイルに写真を取り込む動作を実装します。
AirTap時に撮影を行い、画像ファイルは LocalState フォルダに保存するようにしました。
・CaptureTest.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HoloToolkit.Unity.InputModule;
using System;
using System.IO;
using System.Linq;
using UnityEngine.XR.WSA.WebCam;

public class CaptureTest : MonoBehaviour, IInputClickHandler
{
    private PhotoCapture photoCaptureObject = null;
    // Use this for initialization
    void Start()
    {
        // AirTap時のイベントを設定する
        InputManager.Instance.PushFallbackInputHandler(gameObject);
    }

    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);
    }

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

    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(PictureFileDirectoryPath(), 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");
        }
    }

    /// <summary>
    /// 画像保存ディレクトリパス
    /// 実行環境によって参照ディレクトリを変更する
    /// </summary>
    private string PictureFileDirectoryPath()
    {
        string directorypath = "";
#if WINDOWS_UWP
    // HoloLens上での動作の場合、LocalAppData/AppName/LocalStateフォルダを参照する
    directorypath = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
#else
        // Unity上での動作の場合、Assets/StreamingAssetsフォルダを参照する
        directorypath = UnityEngine.Application.streamingAssetsPath;
#endif
        return directorypath;
    }

    /// <summary>
    /// クリックイベント
    /// </summary>
    public void OnInputClicked(InputClickedEventData eventData)
    {
        Debug.Log("capture");
        // キャプチャを開始する
        PhotoCapture.CreateAsync(true, OnPhotoCaptureCreated);
    }

    // Update is called once per frame
    void Update()
    {
    }
}

上記スクリプトをプロジェクト内のゲームオブジェクトにアタッチします。
f:id:bluebirdofoz:20180307093506j:plain
(カメラ正面に置いてあるのは以前作成したデバッグタブレットオブジェクトです)
bluebirdofoz.hatenablog.com

Capasibilities の設定で"Microphone"と"Webcam"を有効にしておきます。
f:id:bluebirdofoz:20180307093531j:plain

後はアプリを起動して、AirTapを行うと……。
f:id:bluebirdofoz:20180307093550j:plain
LocalState フォルダに画像ファイルが出力されました。成功です。