Contents
はじめに
本来であればHoloLens 2本体のボタンを操作することで撮影可能ですが、開発するAppによっては何かしらのイベントをトリガーに撮影したいというケースもあるかと思います。
そこで今回は、HoloLens 2でMRキャプチャを使ってスクリプトから写真撮影及び撮影したデータの保存とカメラロールにファイルを移動するところまでを紹介していきます。
カメラ撮影部分の説明
カメラ撮影部分に関しては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を生成するやり方についても紹介していますので、そちらもご参照ください。
この記事が何かの参考になれば幸いです。