HoloLens 2でMRキャプチャを使ってスクリプトから写真撮影と保存処理を行う方法
この記事にはアフィリエイト広告および広告が含まれています。

Contents

はじめに

本来であればHoloLens 2本体のボタンを操作することで撮影可能ですが、開発するAppによっては何かしらのイベントをトリガーに撮影したいというケースもあるかと思います。

そこで今回は、HoloLens 2でMRキャプチャを使ってスクリプトから写真撮影及び撮影したデータの保存とカメラロールにファイルを移動するところまでを紹介していきます。

カメラ撮影部分の説明

カメラ撮影部分に関してはUnityのリファレンスを参考に処理を書いています。詳しくは以下のリンクをご覧ください。

Microsoft Unityのフォト ビデオ カメラ

Unity - HoloLens の PhotoCapture

以下のコードはUnityのリファレンスを元に記述しました。

public class SceneCapture
{
    /// <summary> 写真撮影 </summary>
    private PhotoCapture _photoCaptureObject = null;

    private string _filePath;

    private string _filename;

    /// <summary>
    /// 撮影
    /// </summary>
    public void TakePhoto()
    {
        Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();

        // Create a PhotoCapture object
        PhotoCapture.CreateAsync(true, delegate (PhotoCapture captureObject)
        {
            _photoCaptureObject = captureObject;
            CameraParameters cameraParameters = new CameraParameters();
            cameraParameters.hologramOpacity = 0.9f;
            cameraParameters.cameraResolutionWidth = cameraResolution.width;
            cameraParameters.cameraResolutionHeight = cameraResolution.height;
            cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;

            _filename = string.Format(@"CapturedImage{0}_n.jpg", Time.time);
            _filePath = System.IO.Path.Combine(Application.persistentDataPath, _filename);

#if WINDOWS_UWP
            _filePath = System.IO.Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, _filename);
#endif

            // Activate the camera
            _photoCaptureObject.StartPhotoModeAsync(cameraParameters, delegate (PhotoCapture.PhotoCaptureResult result) {
                _photoCaptureObject.TakePhotoAsync(_filePath, PhotoCaptureFileOutputFormat.JPG, OnCapturedPhotoToDisk);
            });
        });
    }

    /// <summary>
    /// 撮影後の保存処理
    /// </summary>
    /// <param name="result"></param>
    private void OnCapturedPhotoToDisk(PhotoCapture.PhotoCaptureResult result)
    {
        if (result.success)
        {

#if WINDOWS_UWP
            var cameraRollFolder = Windows.Storage.KnownFolders.CameraRoll.Path;  
            File.Move(_filePath, Path.Combine(cameraRollFolder, _filename));
#endif

            _photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
        }
        else
        {
            Debug.LogError("Failed to save Photo to disk");
            return;
        }
    }

    /// <summary>
    /// 撮影後の後処理
    /// </summary>
    /// <param name="result"></param>
    private void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
    {
        _photoCaptureObject.Dispose();
        _photoCaptureObject = null;
    }
}

注意するのはhologramOpacityです。これは不透明度と呼ばれているものでUnityのリファレンスだと0.0fが代入されています。これだと撮影しても何も映りません

cameraParameters.hologramOpacity = 0.0f;

そのため、ここの値を1.0fなどに変更すると良いでしょう。

cameraParameters.hologramOpacity = 1.0f;

撮影した写真を書き込む部分の説明

ファイル名と保存する先のパスを選択し、保存処理を行います。

            _filename = string.Format(@"CapturedImage{0}_n.jpg", Time.time);
            _filePath = System.IO.Path.Combine(Application.persistentDataPath, _filename);

#if WINDOWS_UWP
            _filePath = System.IO.Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, _filename);
#endif

            // Activate the camera
            _photoCaptureObject.StartPhotoModeAsync(cameraParameters, delegate (PhotoCapture.PhotoCaptureResult result) {
                _photoCaptureObject.TakePhotoAsync(_filePath, PhotoCaptureFileOutputFormat.JPG, OnCapturedPhotoToDisk);
            });
/// <summary>
/// 撮影後の保存処理
/// </summary>
/// <param name="result"></param>
private void OnCapturedPhotoToDisk(PhotoCapture.PhotoCaptureResult result)
{
    if (result.success)
    {

#if WINDOWS_UWP
        var cameraRollFolder = Windows.Storage.KnownFolders.CameraRoll.Path;  
        File.Move(_filePath, Path.Combine(cameraRollFolder, _filename));
#endif

        _photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
    }
    else
    {
        Debug.LogError("Failed to save Photo to disk");
        return;
    }
}

HoloLens 2のカメラロールに移動

撮影した画像をカメラロールに入れる際の処理は以下の部分です。

var cameraRollFolder = Windows.Storage.KnownFolders.CameraRoll.Path;
File.Move(_filePath, Path.Combine(cameraRollFolder, _filename));

これでカメラロールに撮影した画像が移動されます。

Windows機になるので、#if WINDOWS_UWP が必要になります

処理呼び出し

var sceneCapture = new SceneCapture();
sceneCapture.TakePhoto();

使用する時にインスタンスを生成することで撮影から保存まで行ってくれます。

懸念事項

スクリプトから撮影処理からの保存を行うとCPU負荷が上がるため、一時的にfpsが落ちます。そのため快適な体験を提供するには非同期処理にするなどの対策が必要不可欠となります。

まとめ

HoloLens 2で写真撮影から画像保存、カメラロールへの移動までを紹介しました。

AirTap先でCubeを生成するやり方についても紹介していますので、そちらもご参照ください。

この記事が何かの参考になれば幸いです。

Twitterでフォローしよう

おすすめの記事