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

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

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

Zxingにはいくつかのバーコード解析クラスが存在しています。今回はそのうちのQRコード用のQRCodeReaderクラスを使用します。このQRCodeReaderクラスは解析対象にBinaryBitmapオブジェクトを作成する必要があります。

LuminanceSourceクラスを継承したPreviewFrameLuminanceSourceクラスを作成し,PhotoCamera.GetPreviewBufferYメソッドで取得した輝度情報を格納します。

public class PreviewFrameLuminanceSource : LuminanceSource {

// プレビューフレームを格納するバッファ
public byte[] Buffer { get; set; }

public PreviewFrameLuminanceSource(int width, int height) : base(width, height) {
    Buffer = new byte[width * height];
}

/// <summary>
/// バッファをsbyte[]型で取得する
/// </summary>
public override sbyte[] Matrix {
    get { 
        // Bufferをbyte[]からsbyte[]へキャスト
        return ((Buffer as Array) as sbyte[]); 
    }
}

/// <summary>
///  1ラインずつデータを取得
/// </summary>
public override sbyte[] getRow(int y, sbyte[] row) {
    // 前回確保したrowとサイズが異なる場合,再度確保しなおす
    if (row == null || row.Length < Width) {
        row = new sbyte[Width];
    }

    for (int i = 0; i < Height; i++) {
        row[i] = Convert.ToSByte(Buffer[i * Width + y]);
    }

    return row;
}
}

輝度情報のバッファを格納したPreviewFrameLuminanceSourceオブジェクトを元に,HybridBinarizerクラスを使ってBinaryBitmapオブジェクトを作ります。

QRCodeReader.decodeメソッドでバーコードの解析(デコード)を行います。解析を行いバーコードが発見できなかった場合,ReaderExceptionが発行されます。バーコードが発見できた場合,result.Textにテキストが含まれてきますので,リストボックスへ追加していきます。

// タイマー満了時にプレビューフレームにバーコードが含まれているか解析
void readTimer_Tick(object sender, EventArgs e) {

    // プレビューフレームの取得
    var luminanceSource = new PreviewFrameLuminanceSource(
        (int)camera.PreviewResolution.Width,
        (int)camera.PreviewResolution.Height);
    camera.GetPreviewBufferY(luminanceSource.Buffer);

    // リーダーインスタンス生成
    var reader = new QRCodeReader();

    // バーコード解析用のBitmapを作成
    var binarizer = new HybridBinarizer(luminanceSource);
    var binBitmap = new BinaryBitmap(binarizer);

    Result result = null;
    try {
        // バーコードの解析(デコード)を行う
        result = reader.decode(binBitmap);
    } catch (ReaderException) {
        // プレビューフレーム内にバーコードが見つからなかった場合
        // 読み取り例外のReaderExceptionが発行されてしまう
        return;
    } catch (Exception ex) {
        throw ex;
    }

    // コントロールへのアクセスを行うのでUIスレッドにて非同期で実行
    Dispatcher.BeginInvoke(() => {
        // 既にテキストが含まれていれば追加しない
        if (!BarcodeListBox.Items.Contains(result.Text)) {
            BarcodeListBox.Items.Add(result.Text);
        }
    });
}

写真の撮り方が悪かったのでかなり見えにくいですが,カメラプレビューの上に認識できたバーコードが表示されているのがわかりますでしょうか。

画像

サンプルアプリケーションの実装としては以上です。ライブラリ組み込みも難易度もそれほど高くなく,簡単にバーコードのデコードが出来るのは魅力的ではないでしょうか。

さいごに

今回はカメラを使ったリアルタイムなエフェクト処理とバーコード解析処理をご紹介させて頂きました。

上記で紹介したように延々と画像の入力を受け付けるアプリケーションのほかにも,有効なバーコードをデコードした時点で,その情報をWebAPIを使って取得するようなアプリケーションを作成するのも面白いかもしれませんね。

エフェクト処理は,カメラプレビューと組み合わせて使わなくても,写真編集アプリケーションにも流用が効きそうです。自身のアプリケーションに組み込む際には,好みの画質に調整して頂ければと思います。

今回は以上で終わりです。ありがとうございました。

著者プロフィール

和田健司(わだけんじ)

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/