Windows Phoneアプリケーション開発入門

第37回 Mangoで追加されたカメラ機能を使ってみよう!(3)

この記事を読むのに必要な時間:およそ 9 分

はじめに

前回は,Windows Phone OS 7.1から搭載されたPhotoCameraクラスを使用して静止画撮影の方法についてご紹介しました。

このPhotoCameraクラスには,静止画撮影関係の機能以外にも,プレビュー中のフレーム(画像)をARGB32形式,YCbCr形式,Y成分(輝度情報のみ)の形式で取得することができます。

プレビューフレームを用いることで,リアルタイムでエフェクトをかけながら表示したり,特定のマーカーを探しバーコードを読み取るアプリケーションを開発することができます。

今回は,プレビューフレームを取得する方法と取得したフレームの利用方法についてご紹介いたします。サンプルプロジェクトを2つご用意しましたので,是非ソースコードと一緒に記事を読み進めて頂ければと思います。

ARGB32形式のプレビューフレームを取得してエフェクト処理を行う

冒頭の「CameraPreviewTest_ColorEffect.zip」のほうのサンプルプロジェクトを使用しながらTipsをご紹介します。

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

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

画像

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

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

プレビューフレームを取得するのは簡単です。例としてプレビューフレームをPhotoCamera.GetPreviewBufferArgb32メソッドでバッファーへ書き出しを行い,その後ピクセルデータを分離ストレージへ保存する簡単なコードをご紹介します。

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

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

// 分離ストレージへARGBデータへ保存する
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);
    }
}

上記のコードを実行すると,ARGB32データが分離ストレージに書き出されているはずです。

前回紹介しましたIsolated Strage Explorer Toolを使ってデータを取り出してもよいのですが,ファイルヘッダも付いていないピクセルデータしかないファイルですので,Windowsに付属しているプレビューツールでは見ることができません。

これでは,本当にプレビューフレームを取り出すことができているのか,確認することができません。取り込んだフレームに対してエフェクト処理を施し,画面上に表示するようにひとつ工夫してみましょう。

<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>
        <!-- エフェクト処理後の画像を表示する -->
    <Image Height="310" x:Name="ImageEffect" Stretch="UniformToFill" 
            VerticalAlignment="Bottom" RenderTransformOrigin="0.5,0.5" 
            Margin="20,0,20,60" Width="401" />
</Grid>

Expression BlendでXAMLを表示すると下図のようになります。中央の枠がImageコントロールですので,ここにエフェクト処理をしたプレビューフレームを表示させます。

画像

あとでエフェクト処理を掛けやすいように,PhotoCamera.GetPreviewBufferArgb32メソッドで取得したARGB32データを格納するクラスを作ります。画像の幅と高さ,それと画像データを格納するバッファがプロパティとしてあるだけの簡単なクラスを作成します。

後ほどエフェクト処理を実装しますので,中身のないEffectSepiaToneメソッドを実装しています。

    public class FrameBuffer {

        // 画像を格納するバッファ
        public int[] Buffer { get; set; }

        // バッファに格納する画像の幅
        public int Width { get; set; }

        // バッファに格納する画像の高さ
        public int Height { get; set; }

        public FrameBuffer(int width, int height) {
            Buffer = new int[width * height];
            Width = width;
            Height = height;
        }

        public void EffectSepiaTone() {
            // あとで紹介するメソッドです
        }
    }

著者プロフィール

和田健司(わだけんじ)

1982年10月12日生まれ。大阪で働くプログラマ。Microsoft MVP for Device Application Development(Jul 2010 - Jun 2011)。Windows Mobileに傾倒し今に至る。Windows Mobile向けのTipsを書いています。iPhoneアプリ開発を始めました。嫌いな食べ物はカレー。

URL: http://ch3cooh.jp/
Blog: http://d.hatena.ne.jp/ch3cooh393/

コメント

コメントの記入