はじめに
Windows Phoneには、アプリケーション内で静止画撮影を行う為の基本的なカメラの機能が提供されています。Windows Phone OS 7.1よりサポートされています。
PhotoCameraクラスには静止画撮影、オートフォーカス、フラッシュモードなどの機能を使用するためのメソッドが含まれています。またそれぞれの処理完了のイベントが用意されています。
また、静止画撮影関係の機能以外にも、プレビュー中のフレーム(画像)をARGB32形式、YCbCr形式、Y成分(輝度情報)のみの形式で取得することが出来ます。
プレビューフレームを用いることで、リアルタイムでカラーエフェクトを掛けながら表示したり、特定のマーカーを探しアニメーションを表示するなどの拡張現実(AR)アプリケーションを開発することが可能になりました。
今回、新規にプロジェクトを作成してカメラプレビューを行う方法を紹介したいと思います。サンプルプロジェクトを用意しましたので、是非ソースコードと一緒に記事を読み進めて頂ければと思います。
カメラプレビューを行う前の準備を行う
ツールバーの[ファイル]の[新規作成]から[プロジェクト]を選択し、新しいプロジェクトを作成しましょう。Visual C#のテンプレートから「Windows Phone Application」を選択して、新しいプロジェクトを作成します。プロジェクトの名前は「CameraPreviewTest」にしておきます。
次にWindows Phoneプラットフォームのターゲットを選択します。カメラ機能を使用するには、上述した通りWindows Phone OS 7.1以降である必要がありますので、Windows Phone OSのターゲットは「Windows Phone OS 7.1」を選択しましょう。
カメラ機能を使用するためには、Windows Phone Apllication マニュフェストファイルのWMAppManifest.xmlのCapabilities要素に「ID_CAP_ISV_CAMERA」という権限を追加しておく必要があります。
上記手順どおりにプロジェクトを作成した場合は、デフォルトで権限が追加されていると思いますが、カメラ機能が使えなかったりする場合は、下図スクリーンショットを参考にVisual StudioでWMAppManifest.xmlを開いて、Capabilities要素に「ID_CAP_ISV_CAMERA」を追加しておいてください。
ソリューションエクスプローラーからCameraPreviewTestプロジェクトを右クリックし、「 参照の追加」を選択してください。.NETタブにMicrosoft.XNA.Frameworkがあると思いますので追加を行います。
MainPage.xamlの「LayoutRoot」という名前のGridを以下のコードで置き換えてください。カメラプレビューを表示する為の「PreviewRectangle」という名前の矩形(Rectangle)を追加しています。
矩形を塗りつぶすBrushオブジェクトの一種に、単色で塗りつぶすSolidColorBrushがあります。これと同様に動画で塗りつぶすVideoBrushを使って、カメラデバイスから入力されたプレビューフレームでPreviewRectangleの矩形を塗りつぶします。
< Grid x : Name = "LayoutRoot" Background = "Transparent" >
< Grid . RowDefinitions >
< RowDefinition Height = "Auto" />
< RowDefinition Height = "*" />
</ Grid . RowDefinitions >
< StackPanel x : Name = "TitlePanel" Grid . Row = "0" Margin = "12,17,0,28" >
< TextBlock x : Name = "PageTitle" Text = "CameraPreviewTest"
Margin = "9,-7,0,0"
Style = "{StaticResource PhoneTextTitle2Style}" />
</ StackPanel >
< Grid x : Name = "ContentPanel" Grid . Row = "1" Margin = "12,0,12,0" >
< Rectangle x : Name = "PreviewRectangle" >
< Rectangle . Fill >
< VideoBrush x : Name = "PreviewBrush" />
</ Rectangle . Fill >
</ Rectangle >
</ Grid >
</ Grid >
カメラプレビューを開始する
カメラプレビューを表示させるだけであれば、生成したPhotoCameraオブジェクトをカメラにVideoBrushのソースをPhotoCamera.SetSourceメソッドで設定するだけです。
protected override void OnNavigatedTo ( NavigationEventArgs e ) {
camera = new PhotoCamera ();
PreviewBrush . SetSource ( camera );
}
端末にはカメラデバイスが搭載されていますが、大抵の場合カメラデバイスは端末に対して横向きに搭載されているので、表示の際に回転させる必要があります。
カメラの初期化が完了すると、Initializedイベントが発行されます。カメラの初期化処理完了後にcamera_Initializedメソッドでブラシへ回転処理を適用します。
using System ;
using System . Windows . Navigation ;
using System . Windows . Media ;
using Microsoft . Phone . Controls ;
using Microsoft . Devices ;
namespace CameraPreviewTest {
public partial class MainPage : PhoneApplicationPage {
public MainPage () {
InitializeComponent ();
}
PhotoCamera camera = null ;
protected override void OnNavigatedTo ( NavigationEventArgs e ) {
camera = new PhotoCamera ();
camera . Initialized += camera_Initialized ;
PreviewBrush . SetSource ( camera );
}
protected override void OnNavigatedFrom ( NavigationEventArgs e ) {
if ( camera != null ) {
camera . Dispose ();
camera = null ;
}
}
void camera_Initialized ( object sender , CameraOperationCompletedEventArgs e ) {
if (! e . Succeeded )
return ;
Dispatcher . BeginInvoke (() => {
PreviewBrush . RelativeTransform = new CompositeTransform () {
CenterX = 0.5 , CenterY = 0.5 ,
Rotation = camera . Orientation
};
});
}
}
}
アプリケーションを起動し、ページがフレームでアクティブになったらOnNavigatedToメソッドが呼び出されます。このメソッドにてカメラに対してVideoBrushのソースを設定しているので、カメラプレビューが開始されます。
オートフォーカスを開始する
カメラはピントが合っていないとボケた映像になります。ピントを合わせて綺麗にプレビューさせたり静止画撮影を行う為にはフォーカスを調整する必要があります。PhotoCameraクラスには、Focusという自動でピントを合わせるメソッドがあります。
camera . Focus ();
Windows Phoneの標準のカメラアプリケーションでは、プレビュー画面をタップするとオートフォーカスを行います。サンプルプロジェクトの方でも同じ様に実装してみましょう。カメラプレビューを表示している矩形のPreviewRectangleがタップされるのをトリガーにして、PhotoCamera.Focusメソッドを呼び出します。
MainPage.xamlで配置しているPreviewRectangleにTapイベントのハンドラを追加してください。
< Grid x : Name = "ContentPanel" Grid . Row = "1" Margin = "12,0,12,0" >
< Rectangle x : Name = "PreviewRectangle" Tap = "PreviewRectangle_Tap" >
< Rectangle . Fill >
< VideoBrush x : Name = "PreviewBrush" />
</ Rectangle . Fill >
</ Rectangle >
</ Grid >
AutoFocusCompletedイベントのハンドラを設定して、PhotoCamera.Focusメソッドを使います。フォーカス調整が完了するとcamera_AutoFocusCompletedメソッドが呼ばれます。
private void PreviewRectangle_Tap ( object sender , System . Windows . Input . GestureEventArgs e ) {
if ( camera == null ) {
return ;
}
System . Diagnostics . Debug . WriteLine ( "AutoFocus Start: " + DateTime . Now . ToString ( "HH:mm:ss.fff" ));
camera . AutoFocusCompleted += camera_AutoFocusCompleted ;
camera . Focus ();
}
void camera_AutoFocusCompleted ( object sender , CameraOperationCompletedEventArgs e ) {
camera . AutoFocusCompleted -= camera_AutoFocusCompleted ;
System . Diagnostics . Debug . WriteLine ( "AutoFocus End : " + DateTime . Now . ToString ( "HH:mm:ss.fff" ));
}
実機にサンプルアプリケーションをデプロイしてみました。アプリケーションが起動するとプレビューが始まりますので、画面をタップしオートフォーカス処理を行い、ピントを合わせました。
オートフォーカスを中止する
前述のオートフォーカス処理は少し時間が掛かってしまいます。実機(HTC Mozart)上で、オートフォーカスの開始から終了まで約2秒ほど掛かりました。
おそらく端末によって処理に掛かる時間の加減はありますが、少し時間の掛かる処理であることは間違いありません。処理中にオートフォーカスを中止するには、PhotoCamera.CancelFocusメソッドを使用します。
camera . CancelFocus ();
さいごに
カメラプレビューとオートフォーカスの使い方をご紹介させて頂きました。次回はカメラを使っての静止画撮影とフラッシュモードの使い方についてご紹介させて頂きたいと思います。