iOS7 之後內建 QR code/Bar code 功能,
不用再安裝 ZBar 等第三方 library,方便許多,
使用流程如下:
- configure device
- create session(協助處理input/output)
- add input
- add output
configure device
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]){
if([device lockForConfiguration:&error]) {
CGPoint autofocusPoint = CGPointMake(0.5f, 0.5f);
[device setFocusPointOfInterest:autofocusPoint];
[device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
[device unlockForConfiguration];
}
else{
NSLog(@"configuration error");
}
}
create session
AVCaptureSession *session = [[AVCaptureSession alloc]init];
add input
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if ([session canAddInput:input]) {
[session addInput:input];
}
else {
NSLog(@"can not add input");
}
add output
setMetadataObjectTypes
必需在 addOutput
之後,不然會噴 error[1]。
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
if([session canAddOutput:output]){
[session addOutput:output];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// setMetadataObjectTypes must be call after addOutput
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
}
大致上這樣就完成了,但真正執行時,空白一片,
加個 preview layer 把 camera video 顯示出來,這樣感覺好多了...:D
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = self.view.frame;
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:captureVideoPreviewLayer];
[session startRunning];
20150731 更新:
回來看兩年前的 code 居然還是花了不少時間,決定包成 BarcodeManager 方便以後使用,詳見 github。
[1]*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVCaptureMetadataOutput setMetadataObjectTypes:] - unsupported type found. Use -availableMetadataObjectTypes.'