Windows の組み込みカメラ UI を使った写真とビデオのキャプチャ

この記事では、CameraCaptureUI クラスを使用して、Windows に組み込まれているカメラ UI で写真またはビデオをキャプチャする方法を説明します。 この機能の使い方は簡単です。 わずか数行のコードで、ユーザーがキャプチャした写真やビデオをアプリに取り込むことができます。

独自のカメラ用 UI を用意する場合、またはキャプチャ操作に対してより堅牢で低レベルな制御が必要な場合は、MediaCapture クラスを使用して、独自のキャプチャ操作を実装する必要があります。 詳しくは、「MediaCapture を使った基本的な写真、ビデオ、およびオーディオのキャプチャ」をご覧ください。

注意

アプリで CameraCaptureUI のみを使用する場合は、アプリのマニフェスト ファイルで Web カメラまたはマイク機能を指定しないでください。 指定すると、アプリはデバイスのカメラのプライバシー設定に表示されますが、ユーザーがアプリからのカメラへのアクセスを拒否しても、CameraCaptureUI はメディアをキャプチャできます。

これは、Windows の組み込みのカメラ アプリが、写真、音声、ビデオのキャプチャをボタンを押して開始する必要がある、信頼されているファースト パーティ アプリであるためです。 アプリが CameraCaptureUI を唯一の写真キャプチャ メカニズムとして使用していて、Web カメラまたはマイク機能を指定している場合、ストアに提出するときに Windows アプリケーション認定キット認定が認められない可能性があります。

MediaCapture を使用して、音声、写真、またはビデオをプログラムによってキャプチャする場合は、アプリのマニフェスト ファイルで Web カメラまたはマイク機能を指定する必要があります。

CameraCaptureUI を使った写真のキャプチャ

カメラ キャプチャ UI を使うには、プロジェクトに Windows.Media.Capture 名前空間を含めます。 返された画像ファイルでファイル操作を行うには、Windows.Storage を含めます。

using Windows.Media.Capture;
using Windows.Storage;
#include <winrt/Windows.Media.Capture.h>
#include <winrt/Windows.Media.Playback.h>
#include <winrt/Windows.Storage.h>
using namespace winrt;
using namespace Windows::Media::Capture;
using namespace Windows::Storage;

写真をキャプチャするには、新しい CameraCaptureUI オブジェクトを作成します。 オブジェクトの PhotoSettings プロパティを使うと、写真の画像形式など、返される写真のプロパティを指定することができます。 既定では、カメラのキャプチャ UI では、返される前に写真をトリミングすることができます。 これは、AllowCropping プロパティを使用して無効にすることができます。 この例では、CroppedSizeInPixels を設定して、返される画像のサイズが 200 x 200 ピクセルになるよう要求しています。

注意

モバイル デバイス ファミリのデバイスでは、CameraCaptureUI での画像のトリミングはサポートされていません。 アプリがこれらのデバイスで実行されている場合、AllowCropping プロパティの値は無視されます。

写真をキャプチャすることを指定するには、CaptureFileAsync を呼び出して、CameraCaptureUIMode.Photo を指定します。 キャプチャに成功すると、このメソッドは、画像が格納された StorageFile インスタンスを返します。 ユーザーがキャプチャを取り消した場合、返されるオブジェクトは null になります。

CameraCaptureUI captureUI = new CameraCaptureUI();
captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
captureUI.PhotoSettings.CroppedSizeInPixels = new Size(200, 200); 

StorageFile photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);

if (photo == null)
{
    // User cancelled photo capture
    return;
}
CameraCaptureUI captureUI;
captureUI.PhotoSettings().Format(CameraCaptureUIPhotoFormat::Jpeg);
captureUI.PhotoSettings().CroppedSizeInPixels({ 200, 200 });

StorageFile photo = co_await captureUI.CaptureFileAsync(CameraCaptureUIMode::Photo);

if (!photo)
{
    // User cancelled photo capture
    co_return;
}

キャプチャした写真が格納されている StorageFile は、動的に生成された名前が付けられて、アプリのローカル フォルダーに保存されます。 キャプチャした写真をわかりやすく整理するため、別のフォルダーにファイルを移動することができます。

StorageFolder destinationFolder = 
    await ApplicationData.Current.LocalFolder.CreateFolderAsync("ProfilePhotoFolder", 
        CreationCollisionOption.OpenIfExists);

await photo.CopyAsync(destinationFolder, "ProfilePhoto.jpg", NameCollisionOption.ReplaceExisting);
await photo.DeleteAsync();
StorageFolder destinationFolder =
    co_await ApplicationData::Current().LocalFolder().CreateFolderAsync(L"ProfilePhotoFolder",
        CreationCollisionOption::OpenIfExists);

co_await photo.CopyAsync(destinationFolder, L"ProfilePhoto.jpg", NameCollisionOption::ReplaceExisting);
co_await photo.DeleteAsync();

アプリで写真を使用するために、SoftwareBitmapオブジェクトを作成できます。このオブジェクトは、ユニバーサル Windows アプリのさまざまな機能で使用できます。

まず、プロジェクトに Windows.Graphics.Imaging 名前空間を含めます。

using Windows.Storage.Streams;
using Windows.Graphics.Imaging;
#include <winrt/Windows.Graphics.Imaging.h>
#include <winrt/Windows.Storage.Streams.h>
using namespace Windows::Graphics::Imaging;
using namespace Windows::Storage::Streams;

画像ファイルからストリームを取得するには、OpenAsync を呼び出します。 ストリームのビットマップ デコーダーを取得するには、BitmapDecoder.CreateAsync を呼び出します。 次に、GetSoftwareBitmap を呼び出して、画像の SoftwareBitmap 表現を取得します。

IRandomAccessStream stream = await photo.OpenAsync(FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();
IRandomAccessStream stream = co_await photo.OpenAsync(FileAccessMode::Read);
BitmapDecoder decoder = co_await BitmapDecoder::CreateAsync(stream);
SoftwareBitmap softwareBitmap = co_await decoder.GetSoftwareBitmapAsync();

UI に画像を表示するには、XAML ページで Image コントロールを宣言します。

<Image x:Name="imageControl" Width="200" Height="200"/>
<Image x:Name="imageControl" Width="200" Height="200"/>

XAML ページでソフトウェア ビットマップを使用するには、Windows.UI.Xaml.Media.Imaging 名前空間の using 指定を含めます。

using Windows.UI.Xaml.Media.Imaging;
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
using namespace Windows::UI::Xaml::Media::Imaging;

Image コントロールでは、画像ソースが事前乗算済みアルファを含む (またはアルファを含まない) BGRA8 形式である必要があります。 静的メソッドの SoftwareBitmap.Convert を呼び出して、目的の形式の新しいソフトウェア ビットマップを作成します。 次に、新しい SoftwareBitmapSource オブジェクトを作成して SetBitmapAsync を呼び出し、ソフトウェア ビットマップをソースに割り当てます。 最後に、キャプチャした写真を UI に表示できるように、Image コントロールの Source プロパティを設定します。

SoftwareBitmap softwareBitmapBGR8 = SoftwareBitmap.Convert(softwareBitmap,
        BitmapPixelFormat.Bgra8, 
        BitmapAlphaMode.Premultiplied);

SoftwareBitmapSource bitmapSource = new SoftwareBitmapSource();
await bitmapSource.SetBitmapAsync(softwareBitmapBGR8);

imageControl.Source = bitmapSource;
SoftwareBitmap softwareBitmapBGR8 = SoftwareBitmap::Convert(softwareBitmap,
    BitmapPixelFormat::Bgra8,
    BitmapAlphaMode::Premultiplied);

SoftwareBitmapSource bitmapSource;
co_await bitmapSource.SetBitmapAsync(softwareBitmapBGR8);

imageControl().Source(bitmapSource);

CameraCaptureUI を使ったビデオのキャプチャ

ビデオをキャプチャするには、新しい CameraCaptureUI オブジェクトを作成します。 オブジェクトの VideoSettings プロパティを使うと、ビデオの形式など、返されるビデオのプロパティを指定することができます。

ビデオをキャプチャするには、CaptureFileAsync を呼び出して、Video を指定します。 キャプチャに成功すると、このメソッドは、ビデオが格納された StorageFile インスタンスを返します。 キャプチャを取り消した場合、返されるオブジェクトは null になります。

CameraCaptureUI captureUI = new CameraCaptureUI();
captureUI.VideoSettings.Format = CameraCaptureUIVideoFormat.Mp4;

StorageFile videoFile = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Video);

if (videoFile == null)
{
    // User cancelled photo capture
    return;
}
CameraCaptureUI captureUI;
captureUI.VideoSettings().Format(CameraCaptureUIVideoFormat::Mp4);

StorageFile videoFile = co_await captureUI.CaptureFileAsync(CameraCaptureUIMode::Video);

if (!videoFile)
{
    // User cancelled photo capture
    co_return;
}

キャプチャしたビデオ ファイルをどのように使うかは、アプリのシナリオによって異なります。 この記事の残りの部分では、キャプチャした 1 つ以上のビデオからメディア コンポジションをすばやく作成し、UI に表示する方法を説明します。

まず、ビデオ コンポジションを表示する MediaPlayerElement コントロールを XAML ページに追加します。

<MediaPlayerElement x:Name="mediaPlayerElement" Width="320" Height="240" AreTransportControlsEnabled="True"/>

カメラ キャプチャ UI からビデオ ファイルが返されたら、CreateFromStorageFile を呼び出して、新しい MediaSource を作成します。 MediaPlayerElement に関連付けられている既定の MediaPlayerPlay メソッドを呼び出してビデオを再生します。

mediaPlayerElement.Source = MediaSource.CreateFromStorageFile(videoFile);
mediaPlayerElement.MediaPlayer.Play();
mediaPlayerElement().Source(MediaSource::CreateFromStorageFile(videoFile));
mediaPlayerElement().MediaPlayer().Play();