Windows Phone PhotoCameraの画像取得と編集
UX-TVに対する質問(On Twitter)を見ていて、そういえばMSCのセッションのフォローが中途半端に終わっていたなと思い出し、急遽ポスト。PhotoCameraの画像データを保存したり、画像を編集したりする辺りの基本コードを紹介します。
PhotoCameraを使う場合には、以下のコードで先ず初期化しておきます。
using Microsoft.Devices;
・・・
// クラスメンバー変数としてカメラのインスタンスを宣言
private PhotoCamera photoCamera;
・・・
// カメラインスタンス作成
photoCamera = new PhotoCamera(CameraType.Primary);
// カメラ初期化完了時にコールされるメソッドを登録
photoCamera.Initialized += new EventHandler<CameraOperationCompletedEventArgs>(photoCamera_Initialized);
// イメージキャプチャ時にコールされるメソッドを登録
photoCamera.CaptureImageAvailable += new EventHandler<ContentReadyEventArgs>(photoCamera_CaptureImageAvailable);
他にサムネイルイメージキャプチャ完了を知らせるイベントもありますが、ここでは省略します。それからフラッシュ(というかライトというか)の点灯は、Initializedイベントが発火した後(つまり初期化完了以降)でしか制御できないというTipsをはさみながら、次にイメージキャプチャ時の説明に移ります。
ボタンのクリックイベントハンドラやスクリーンのタップイベントハンドラなどで、
photoCamera.CaptureImage();
とCaptureImage()メソッドをコールすると、画像キャプチャー機能が働き、終わったら、photoCamera_CaptureImageAvailableがコールされます。
void photoCamera_CaptureImageAvailable(object sender, ContentReadyEventArgs e)
{
// このハンドラをコールするスレッドは外部スレッドなので、UIを操作する場合は、以下の様にDispatcherにデレゲート
Deployment.Current.Dispatcher.BeginInvoke(delegate()
{
BitmapImage photoImage = new BitmapImage();
photoImage.SetSource(e.ImageStream);
上の図のように、BitmapImageインスタンスを一つ作り、SetSourceメソッドでイベント引数eで渡されたImageStreamをソースとして登録します。
これで、プログラム上で、PhotoCameraが撮った画像を、BitmapImageとして扱うことが出来るようになります。
更に、画像にテキストや図形を重ねたい場合は、
Image image = new Image();
image.Source = photoImage;
Canvas videoCanvas = new Canvas();
videoCanvas.Children.Add(image);
と、今度はImageクラスのインスタンスを一つ作って、photoImageを渡し、Canvasを一つ作って、作成したimageをChildrenに加えれば、Canvasに書き込まれたことになります。後は、このCanvasにテキストや図形を貼り付けていけば、写真と図を組み合わせた画像が出来上がります。例えば、
// デバイスの姿勢を記録
TextBlock tbDir = new TextBlock();
tbDir.Text = String.Format("Direction:Yaw={0:0.000},Pitch={1:0.000},Row={2:0.000}", motion.CurrentValue.Attitude.Yaw, motion.CurrentValue.Attitude.Pitch, motion.CurrentValue.Attitude.Roll);
tbDir.FontSize = 20;
Canvas.SetTop(tbDir, 360);
Canvas.SetLeft(tbDir, 10);
videoCanvas.Children.Add(tbDir);
と書けば、Motionセンサーから取得した姿勢情報を、写真画像に重ねられます。普通にCanvasに描き込む要領で、RectangleやPolygonを描いていけば図も重ねることが出来ます。このコードでは、videoCanvasは、コードの中で作成していますが、XAMLで、UIの一部として宣言していれば、写真画像とテキストや図形を重ねた絵を表示可能です(ま、あたりまえですね)
最後に、作成した画像をファイルに保存する方法を説明します。
WriteableBitmap photoBitmap = new WriteableBitmap(videoCanvas,null);
photoBitmap.Invalidate();
写真画像、テキスト、図形、その他諸々を重ねたキャンバスをソースとして、WriteableBitmapインスタンスを作成します。
ここで、Invalidate()メソッドをコールするのがミソ。このメソッドをコールして初めてキャンバスのChildrenに追加したエレメントが描画されるようなので、これをやらないと、何も画像は出来上がりません。絶対に忘れてはいけないメソッドコールです。
後は、
// テンポラリにJPEGファイルを作成して、IsolatedStorageに保存
string fileName = String.Format("arsample{0}.jpg", DateTime.Now.ToString("yyyyMMdd_HHmmss"));
IsolatedStorageFile myStorage = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream tmpFileStream = myStorage.OpenFile(fileName, FileMode.Create, FileAccess.Write);
photoBitmap.SaveJpeg(tmpFileStream, photoBitmap.PixelWidth, photoBitmap.PixelHeight, 0, 100);
の流れで処理をすれば、ファイルの出来上がり。ここではIsolatedStorageに蓄積していますが、別の場所でも全然構いません。
AR動画を表示しながら、画像キャプチャを行い、位置情報やその他の情報を書き込むサンプルは、https://mangorealarcamera.codeplex.com/ で公開しているので、参考にしてくださいね。
Comments
- Anonymous
November 22, 2011
As your thinking,fully agree with your thoughts. Continue to write <a href="www.mlfhardwoodflooringltd.ca ">hardwood flooring in toronto</a> and tell us a great job