QRCodeReaderを使ってみる

先日、QRCodeを作るライブラリを試したので、今度は読み取るライブラリを試してみた。
*QRコードは(株)デンソーウェーブの登録商標です

Get Adobe Flash player


*CPU負荷の高い処理を行っているので、試し終わったらリロードすることをお勧めします。
*「カメラとマイクへのアクセス」ダイアログが出ている最中はCPU負荷はほとんどありません。

ライブラリは、QRCodeReaderを使った。
やっていることはReadQrCodeSampleほぼそのまま。コードを見渡しやすくすることを目的にUIを簡素化した。ライブデモがあると便利かなと。

[sourcecode language=”as3″]
/**************************************************************************
* LOGOSWARE Class Library.
*
* Copyright 2009 (c) LOGOSWARE (http://www.logosware.com) All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
**************************************************************************/
package
{
import com.logosware.event.QRdecoderEvent;
import com.logosware.event.QRreaderEvent;
import com.logosware.utils.QRcode.GetQRimage;
import com.logosware.utils.QRcode.QRdecode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.geom.ColorTransform;
import flash.media.Camera;
import flash.media.Video;
import flash.text.TextField;
import flash.utils.Timer;

/**
* QRコード解析クラスの使用例です
* Kenichi UENOのReadQrCodeSampleを元に、
* コードを見渡しやすくすることを目的にUIを簡素化しました。
* @author umhr
*/
[SWF(width = 465, height = 465, backgroundColor = 0x000000, frameRate = 30)]
public class ReadQrCode extends Sprite
{
// QRCodeライブラリ関連
private var _getQRimage:GetQRimage;
private var _qrDecode:QRdecode = new QRdecode();

// カメラ管理関連
private const SRC_SIZE:int = 320;
private var _cameraTimer:Timer = new Timer(2000);
private var _cameraView:Sprite = new Sprite();
private var _camera:Camera;
private var _video:Video = new Video(SRC_SIZE, SRC_SIZE);

// ガイド関連
private var _guide:Shape = new Shape();
private var _count:int = 0;

// 結果表示関連
private var _resultTextField:TextField = new TextField();
private var _textArray:Array = ["", "", ""];

/**
* コンストラクタ
*/
public function ReadQrCode():void {
addChild( buildResultView() );

// カメラの存在確認。2秒に一回確認する。
_cameraTimer.addEventListener(TimerEvent.TIMER, getCamera);
_cameraTimer.start();
getCamera();
}

/**
* カメラの接続をチェックします
*/
private function getCamera(event:TimerEvent = null):void{
_camera = Camera.getCamera();
if ( _camera == null ) {
_resultTextField.text = "no camera detected.";
} else {
_cameraTimer.removeEventListener(TimerEvent.TIMER, getCamera);
_cameraTimer.stop();
_resultTextField.text = "";
start();
}
}

/**
* 画像解析クラスにカメラ画像を渡し、解析完了イベントを監視します
*/
private function start():void {
addChild( buildCameraView() );

// QRCodeの読み取り
_getQRimage = new GetQRimage(_video);
// QRコードを発見したらデコーダーに渡す
_getQRimage.addEventListener(QRreaderEvent.QR_IMAGE_READ_COMPLETE, onQrImageReadComplete);
// デコードが完了したら結果テキストを表示する
_qrDecode.addEventListener(QRdecoderEvent.QR_DECODE_COMPLETE, onQrDecodeComplete);

this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

/**
* カメラの表示部分を作成
*/
private function buildCameraView():Sprite {
_camera.setQuality(0, 100);
_camera.setMode(SRC_SIZE, SRC_SIZE, 15, true );
_video.attachCamera( _camera );

_cameraView.addChild( _video );
_cameraView.x = int((465 – SRC_SIZE) * 0.5);
_cameraView.y = 15;

// QRCodeを読み込ませるためのガイド。読み込み状態を知らせる役割も持つ。
// ガイド自体に判別上の意味は無く、UI的な役割のみを担っていると思われる。
_guide.graphics.lineStyle(2, 0xFF0000);
_guide.graphics.drawPath(Vector.<int>([1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2]), Vector.<Number>([30, 60, 30, 30, 60, 30, 290, 60, 290, 30, 260, 30, 30, 260, 30, 290, 60, 290, 290, 260, 290, 290, 260, 290]));
_cameraView.addChild(_guide);
return _cameraView;
}

/**
* 結果表示用 TextField 作成
*/
private function buildResultView():TextField {
_resultTextField.width = 465 – 16;
_resultTextField.height = 50;
_resultTextField.wordWrap = true;
_resultTextField.multiline = true;
_resultTextField.border = true;
_resultTextField.background = true;
_resultTextField.backgroundColor = 0xFFFFFF;
_resultTextField.x = 8;
_resultTextField.y = 465 – _resultTextField.height – 8;
return _resultTextField;
}

/**
* 解析を毎フレーム行う
*/
private function onEnterFrame(event:Event):void{
if( _camera.currentFPS > 0 ){
_getQRimage.process();
_count ++;
if (_count == 0) {
// ガイドの色を赤に戻す
_guide.transform.colorTransform = new ColorTransform(1, 0, 0, 1, 255, 0, 0, 0);
}
}
}

/**
* QRコードを発見したらデコーダーに渡す
*/
private function onQrImageReadComplete(event:QRreaderEvent):void {
_resultTextField.text = "QRCode候補を検知しました\n";
_qrDecode.setQR(event.data); // QRreaderEvent.data: QRコード配列
_qrDecode.startDecode(); // デコード開始
}

/**
* デコードが完了したら結果テキストを表示する
*/
private function onQrDecodeComplete(event:QRdecoderEvent):void {
_resultTextField.appendText("QRCodeのデコードが完了しました。3回取得してチェックします。\n");
// ガイドの色を青にして、取得中であることを示す
_guide.transform.colorTransform = new ColorTransform(0, 0, 1, 1, 0, 0, 255, 0);
_count = -20;

// 誤認識があるため、3回連続して同じだった場合のみ、取得とする
_textArray.shift();
_textArray.push(event.data);// QRdecoderEvent.data: 解析文字列
trace(event.data);
if ( _textArray[0] == _textArray[1] && _textArray[1] == _textArray[2] ) {
_resultTextField.text = event.data;
}
}
}
}
[/sourcecode]