QRコード読み取りソフト(ZXing)を使った簡単なアプリ
iPhoneで動く、オープンソースのQRコード読み取りソフトとして ZXing ("Zebra Crossing") があります。このプロジェクトには iPhone 用のサンプルアプリ barcodes が入っていますが、色々な機能を持たせているのでQRコード読み取りライブラリーの使い方を知るには複雑すぎます。そこでカメラで画像を撮りQRコード読み取りを行う簡単なアプリを作ってみました。
サンプル アプリ
ZXingのQRコード読み取りライブラリー Decoder は Decoder.hのメソッドと、DecoderDelegate.hに定義されているデリゲートメソッドを以下の流れで使います。
- Decodeの初期化は initWithNibName:bundle:内で行います
- decodeImage:cropRect: メソッドで画像と画像の範囲を指定して読み取りを開始
- decoder:didDecodeImage:usingSubset:withResult: 読み取りが成功するとこのメソッドが呼ばれます。読み取った結果はwithResult:に入っています。
- decoder:failedToDecodeImage:usingSubset:reason: 読み取りが失敗するとこのメソッドが呼ばれます。
- decoder:willDecodeImage:usingSubset: 読み取り開始時に呼ばれます。 usingSubsetは読み取りで使われる画像です。
- decoder:decodingImage:usingSubset:progress: 読み取り中に呼び出され進行状況がわかります。
QRDecodeViewController.h
#import <UIKit/UIKit.h> #import "Decoder.h" #import "DecoderDelegate.h" #import "ScannedImageView.h" #import "TwoDDecoderResult.h" @interface QRDecodeViewController : UIViewController <DecoderDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate> { IBOutlet ScannedImageView *imageView; IBOutlet UILabel *decodedText; Decoder *decoder; } @property (nonatomic, retain) Decoder *decoder; @property (nonatomic, retain) ScannedImageView *imageView; - (IBAction)onPushCapture:(id)sender; @end
QRDecodeViewController.m (一部)
#import "QRDecodeViewController.h" @implementation QRDecodeViewController @synthesize imageView; @synthesize decoder; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { Decoder *d = [[Decoder alloc] init]; self.decoder = d; d.delegate = self; [d release]; } return self; } - (IBAction)onPushCapture:(id)sender { decodedText.text = @""; UIImagePickerController* picker = [[UIImagePickerController alloc] init]; picker.sourceType = UIImagePickerControllerSourceTypeCamera; picker.delegate = self; picker.allowsEditing = NO; [self presentModalViewController:picker animated:NO]; } - (void)decodeImage:(UIImage *)image { CGSize size = [image size]; CGRect cropRect = CGRectMake(size.width / 4, size.height / 4, size.width / 2, size.height / 2); [image retain]; [self.decoder decodeImage:image cropRect:cropRect]; [image release]; } - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo { [[picker parentViewController] dismissModalViewControllerAnimated:NO]; [self.imageView setImage:image]; [self performSelector:@selector(decodeImage:) withObject:image afterDelay:0.2]; decodedText.text = @"decoding..."; } - (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset { } - (void)decoder:(Decoder *)decoder decodingImage:(UIImage *)image usingSubset:(UIImage *)subset progress:(NSString *)message { } - (void)decoder:(Decoder *)decoder didDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset withResult:(TwoDDecoderResult *)twoDResult { [self.imageView setImage:subset]; decodedText.text = twoDResult.text; } - (void)decoder:(Decoder *)decoder failedToDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset reason:(NSString *)reason { [self.imageView setImage:subset]; decodedText.text = @"Failed to decode"; }
ZXing から QR Decoder の切り出し方法
- QR Decoder本体 cpp/core をプロジェクトにコピーします。今回は CoreSrc というグループにしました このソースが参照出来るように includeのパスを設定します。
- QR Decoder は xzingcore という static library にします。そのライブラリを アプリの依存関係に指定します。
- QR Decoder から Objective-Cのソース TwoDDecoderResult、ScannedImageView、Decoder、DecoderDelegate、GrayBytesMonochromeBitmapSource をコピーします。
- Decoder.m は Decoder.mm にしないとエラーが出ました。ZXingでは出てないので何か設定が抜けているのかも
- iPhone SDK にある libiconv2.dylib を Framework に追加
一昨日に行ったので少し抜けてるかもしれません。上手く行かなかったらコメント下さい。