iOS7で追加されたバーコード読み込みを試す
iOSでバーコードを読み取ろうと思うと、ZXingというサードパーティ製のライブラリを利用する必要があった。
iOS7ではバーコード読み取り用のライブラリがデフォルトで入っており、簡単に利用することができる。
バーコード以外にもQRコードなどの利用頻度高そうなものも(イマサラ)追加されている。
コードの種類 | 定数 |
---|---|
UPC-E | AVMetadataObjectTypeUPCECode |
Code 39 | AVMetadataObjectTypeCode39Code |
Code 39 | mod 43 AVMetadataObjectTypeCode39Mod43Code |
EAN-13(JANコード標準タイプ) | AVMetadataObjectTypeEAN13Code |
EAN-8(JANコード短縮タイプ) | AVMetadataObjectTypeEAN8Code |
Code 93 | AVMetadataObjectTypeCode93Code |
Code 128 | AVMetadataObjectTypeCode128Code |
PDF417 | AVMetadataObjectTypePDF417Code |
QRコード | AVMetadataObjectTypeQRCode |
Aztec code | AVMetadataObjectTypeAztecCode |
(参考)人の顔 | AVMetadataObjectTypeFace |
中でも人の顔なんかは複数人いてもちゃんと読み取れるらしい・・・
今回はxibでバーコード読み取り時のカメラを表示させるビューを用意しておいて、 そこにカメラの映像を貼り付けるやり方を書いています。
#import <AVFoundation/AVFoundation.h> #import <AudioToolbox/AudioServices.h> @interface BarcodeViewController : UIViewController<AVCaptureMetadataOutputObjectsDelegate>{ AVCaptureSession *_session; AVCaptureDevice *_device; AVCaptureDeviceInput *_input; AVCaptureMetadataOutput *_output; AVCaptureVideoPreviewLayer *_prevLayer; UIView *_highlightView; IBOutlet UIView *barcodeView; NSString *getBarcodeString; } @property (weak, nonatomic) IBOutlet UIView *barcodeView;
viewdidloadは簡単に・・・
getBarcodeString = nil; [self barcodeCap];
メインの部分の実装
-(void)barcodeCap{ _highlightView = [[UIView alloc] init]; _highlightView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin; _highlightView.layer.borderColor = [UIColor redColor].CGColor; _highlightView.layer.borderWidth = 3; [self.barcodeView addSubview:_highlightView]; _session = [[AVCaptureSession alloc] init]; _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; NSError *error = nil; _input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error]; if (_input) { [_session addInput:_input]; } else { NSLog(@"Error: %@", error); } _output = [[AVCaptureMetadataOutput alloc] init]; [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; [_session addOutput:_output]; _output.metadataObjectTypes = [_output availableMetadataObjectTypes]; _prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session]; _prevLayer.frame = self.barcodeView.bounds; _prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; [self.barcodeView.layer addSublayer:_prevLayer]; AVCaptureConnection *con = _prevLayer.connection; con.videoOrientation = AVCaptureVideoOrientationLandscapeLeft; [_session startRunning]; [self.barcodeView bringSubviewToFront:_highlightView]; } - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ CGRect highlightViewRect = CGRectZero; AVMetadataMachineReadableCodeObject *barCodeObject; NSString *detectionString = nil; NSArray *barCodeTypes = @[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code]; for (AVMetadataObject *metadata in metadataObjects) { for (NSString *type in barCodeTypes) { if ([metadata.type isEqualToString:type]){ barCodeObject = (AVMetadataMachineReadableCodeObject *)[_prevLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata]; highlightViewRect = barCodeObject.bounds; detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue]; break; } } if (detectionString != nil){ NSLog(@"読み込んだのは%@",detectionString); AudioServicesPlaySystemSound(1000); getBarcodeString = detectionString; break; } } _highlightView.frame = highlightViewRect; }
AVCaptureConnection *con = _prevLayer.connection;
con.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
は無くてもOK。
横画面表示させるときに必要ってだけ。
おそらくカメラアプリを作るときと似てるんじゃないかと思います。
NSArray *barCodeTypes = @[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code];
この配列に認識させたいタイプを記載しておくだけです。
今回はバーコードなので、2つ入れていますが、QRコードだけの場合はAVMetadataObjectTypeQRCode
を入れることになります。
以上!