Windows PhoneでPhotoCameraクラスを使ってプレビューフレームを取得する

By | 2013/04/22
Pocket

Windows Phone OS 7.1から対応されたPhotoCameraクラスを利用し、アプリケーションからカメラ機能を使用する準備と実際にプレビューをおこなうまでについては、「PhotoCameraクラスを使うための前準備」「カメラプレビューを行う」をご覧ください。

本記事内では、カメラプレビュー中に実際に表示されているプレビューフレームを取得してみましょう。

## プレビューフレームを取得するトリガーを準備する

トリガーとしてApplicationBarに下図のように3つのメニューアイテムを並べてみましょう。

MainPage.xaml のApplicationBar.MenuItemsにApplicationBarMenuItemを3つ追加します。追加したメニューアイテムには、それぞれ「ARGB32」「Y」「YCbCr」のプレビューフレームを取得するトリガーとなるClickイベントのハンドラを設定しています。

<!-- アプリケーションバー -->
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" Mode="Minimized">
    <shell:ApplicationBar.MenuItems>
        <shell:ApplicationBarMenuItem x:Name="menuItemGetRGBFrame"
            Text="Get GRB Preview Frame" Click="menuItemGetRGBFrame_Click" />
        <shell:ApplicationBarMenuItem x:Name="menuItemGetYFrame"
            Text="Get Y Preview Frame" Click="menuItemGetYFrame_Click" />
        <shell:ApplicationBarMenuItem x:Name="menuItemGetYCbCrFrame"
            Text="Get YCbCr Preview Frame" Click="menuItemGetYCbCrFrame_Click" />
    </shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

トリガーを用意しましたので、それぞれの場合の処理を紹介していきたいと思います。

## プレビュー中のフレームをARGBフォーマットで取得する

Microsoft.Devices名前空間のPhotoCamera.GetPreviewBufferArgb32メソッドで、ARGB32フォーマットでプレビュー中に表示されている画像(プレビューフレーム)を取得します。

Windows Phone 7でもPCでも同じですが、ディスプレイに表示されている画面はピクセルという最小単位で構成されています。各ピクセルはピクセルの不透明度を示すアルファ値を持っています。

上位8ビットにはアルファ値が格納されています。アルファ値は不透明度を表した値で、アルファ値が最大(255)の場合は不透明に、0の場合は透明となります。

下位24ビットRGB値が格納されています。RGBとは三原色(R成分、G成分、B色成分)の値が、それぞれ8ビットずつ格納されています。このRGBはRed,Green,Blueの頭文字を取ったものです。

このARGB32データを取得するには、プレビューフレームを格納するバッファを用意し、PhotoCamera.GetPreviewBufferArgb32メソッドを使用して画像情報を書き出します。

    // プレビューフレームを取得
    camera.GetPreviewBufferArgb32(pixelData);

生データで取得しても確認する方法がありません。一度プレビューフレームを分離ストレージへ保存してみましょう。

バッファへ書き出しを行ったARGB32データを分離ストレージへ保存します。

int型の数値をバイト配列を

int[]型ですのでそのままStreamに書き込むことが出来ません。BitConverter.GetBytesメソッドを使って

プレビューフレームは
バイト配列から

バイト列(byte型の要素からなる配列)と数値を相互に変換するためのメソッドは、BitConverterクラス()にまとめられている。

int型の整数値を

System名前空間にあるBitConverterクラスのGetBytesメソッドを

private void menuItemGetRGBFrame_Click(object sender, EventArgs e) {

    // プレビューフレームを取得するバッファーを確保する
    double pixelSize = camera.PreviewResolution.Width * camera.PreviewResolution.Height;
    int[] pixelData = new int[(int)pixelSize];
    
    // プレビューフレームを取得
    camera.GetPreviewBufferArgb32(pixelData);

    // int[]のバッファーをbyte単位にコンバートして分離ストレージに書き込む
    using (var store = IsolatedStorageFile.GetUserStoreForApplication())
    using (var strm = store.CreateFile("preview.rgb")) {
        foreach (int pixel in pixelData) {
            var bytes = BitConverter.GetBytes(pixel);
            strm.Write(bytes, 0, bytes.Length);
        }
    }

}

これで名前のARGBフォーマットのデータを取り出してもよいのですが、Windowsに付属しているプレビューツールでは見ることが出来ません。これでは本当に情報が取れているのかわからないため、WriteableBitmap

private void menuItemGetRGBFrame_Click(object sender, EventArgs e) {

    // プレビューフレームを取得するバッファーを確保する
    double pixelSize = camera.PreviewResolution.Width * camera.PreviewResolution.Height;
    int[] pixelData = new int[(int)pixelSize];
    
    // プレビューフレームを取得
    camera.GetPreviewBufferArgb32(pixelData);

    // バッファーをWriteableBitmapへコピー
    WriteableBitmap bmp = new WriteableBitmap((int)camera.PreviewResolution.Width, (int)camera.PreviewResolution.Height);
    pixelData.CopyTo(bmp.Pixels, 0);

    // 分離ストレージへJPEGデータへ保存する
    using (var store = IsolatedStorageFile.GetUserStoreForApplication())
    using (var strm = store.CreateFile("preview.rgb")) {
        bmp.SaveJpeg(strm, (int)camera.PreviewResolution.Width, (int)camera.PreviewResolution.Height, 90, 100);
    }

}

## プレビュー中のフレームをYCbCrフォーマットで取得する

Microsoft.Devices名前空間のPhotoCamera.GetPreviewBufferYCbCrメソッドを利用すると、YCbCrフォーマットでプレビュー中のフレームを取得することが出来ます。YCbCrフォーマットは、輝度情報Yと2つの輝度情報(Cb、Cr)を使って表現します。

RGB形式と比べると輝度情報(白黒)と色差情報が分かれている為、カラーエフェクトを掛けた処理を行うのに向いているかもしれません。

またYCbCrからARGB32への変換は可能でして、MSDNオンラインライブラリにWindows Phoneにおける色空間の変換について書かれた記事「Camera Color Conversion (YCbCr to ARGB) for Windows Phone」があります。

日本語で書かれたYCbCrからRGBとRGBからYCbCrへの変換式については、こちらの「[RGB→YCbCr・YCbCr→RGB](http://eseuta.mine.nu/colorspace.html)」の記事が参考になります。

## プレビュー中のフレームをYフォーマットで取得する

輝度情報を取得します。色差がなく輝度情報のみですので、白黒になります。

## 参考

* [PhotoCamera.GetPreviewBufferArgb32 メソッド](http://msdn.microsoft.com/en-us/library/microsoft.devices.photocamera.getpreviewbufferargb32%28v=VS.92%29.aspx)
* [PhotoCamera.GetPreviewBufferY メソッド](http://msdn.microsoft.com/en-us/library/microsoft.devices.photocamera.getpreviewbuffery%28v=VS.92%29.aspx)
* [PhotoCamera.GetPreviewBufferYCbCr メソッド](http://msdn.microsoft.com/en-us/library/microsoft.devices.photocamera.getpreviewbufferycbcr%28v=VS.92%29.aspx)