ホロレンズのウェブカメラで写真を撮るには PhotoCapture API を使用します。PhotoCapture API を使用するには ウェブカメラ と マイク の機能を有効にする必要があります。以下の例では、PhotoCapture 機能を使って写真を撮る方法と、それを Unity の ゲームオブジェクト に表示する方法を紹介します。
using UnityEngine;
using System.Collections;
using System.Linq;
using UnityEngine.VR.WSA.WebCam;
public class PhotoCaptureExample : MonoBehaviour {
PhotoCapture photoCaptureObject = null;
Texture2D targetTexture = null;
// これを使って初期化します
void Start() {
Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
// PhotoCapture オブジェクトを作成します
PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject) {
photoCaptureObject = captureObject;
CameraParameters cameraParameters = new CameraParameters();
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
// カメラをアクティベートします
photoCaptureObject.StartPhotoModeAsync(cameraParameters, delegate (PhotoCapture.PhotoCaptureResult result) {
// 写真を撮ります
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
});
});
}
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame) {
// ターゲットテクスチャに生画像データをコピーします
photoCaptureFrame.UploadImageDataToTexture(targetTexture);
// テクスチャが適用されるゲームオブジェクトを作成
GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
Renderer quadRenderer = quad.GetComponent<Renderer>() as Renderer;
quadRenderer.material = new Material(Shader.Find("Custom/Unlit/UnlitTexture"));
quad.transform.parent = this.transform;
quad.transform.localPosition = new Vector3(0.0f, 0.0f, 3.0f);
quadRenderer.material.SetTexture("_MainTex", targetTexture);
// カメラを非アクティベート化します
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result) {
// photo capture のリソースをシャットダウンします
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
}
画像をメモリにキャプチャすると、PhotoCaptureFrame が返されます。PhotoCaptureFrame
には、ネイティブの画像データと、画像の取得場所を示す空間の行列の両方が含まれています。
画像をメモリにキャプチャすると、キャプチャされた画像をシェーダーで参照したり、ゲームオブジェクトに適用することができます。PhotoCaptureFrame
から画像データを抽出する方法は 3 つあります。
Access the image data as a Texture2D. This is the most common way to extract image data, because most components in Unity understand how to access image data in a Texture2D. Once your image has been captured to memory, you need to upload the image data into a Texture2D. Once the image data is uploaded into a Texture2D, you can then begin referencing that image data in materials, scripts, or any other relevant element of your project. The Unity API Documentation has an example which demonstrates how to capture a photo to memory and then upload it to a Texture2D. See WebCam.PhotoCapture.TakePhotoAsync to learn how to capture a photo to a Texture2D. Uploading the image data to a Texture2D via the upload command is the easiest way to start working with your image data in Unity. The upload operation happens on the main thread. This operation is resource-intensive and can affect the performance of your project.
Capture the native image data as a WinRT IMFMediaBuffer. See Microsoft’s documentation on IMFMediaBuffer to learn more. Make a copy of the native image data by passing a byte list into the PhotoFrame.CopyRawImageDataIntoBuffer function. Please note that the copy operation occurs on the main thread. This operation is resource-intensive and can affect the performance of your project.
独自のプラグインを作成したり、イメージデータを別のスレッドで処理したりする場合は、PhotoFrame.GetUnsafePointerToBuffer 関数を使用してネイティブの画像データへのポインターを取得します。返されるポインターは、IMFMediaBuffer Component Object Model (COM) へのポインターです。詳細は、Microsoft のドキュメント IMFMediaBuffer および、 Component Object Models を参照してください。この関数を呼び出すと、COM オブジェクトへの参照が追加されます。リソースが不要になったときに、マニュアルで参照を解放する必要があります。