AVCaptureMetadataOutputObjectsDelegate處,怎麼也得不到回調。然後各種琢磨,終於在現在搞明白是什麼一個情況。先上修改前的代碼
- (void)prepareForScan{
NSError *error;
self.captureSession = [[AVCaptureSession alloc] init];
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
/****************Device****************/
self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//更改這個設置的時候必須先鎖定設備,修改完後再解鎖,否則崩潰
if ([self.device lockForConfiguration:NULL]) {
if ([self.device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
[self.device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
}
[self.device unlockForConfiguration];
}
/****************Device****************/
/****************AVCaptureDeviceInput****************/
AVCaptureDeviceInput *input = [[AVCaptureDeviceInput alloc] initWithDevice:self.device error:&error];
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您的攝像頭打不開,請退出重試,或者前往“設置”,找到“快遞員”,打開攝像頭權限" delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[alert show];
NSLog(@"error=%@",error);
}
if ([self.captureSession canAddInput:input]) {
[self.captureSession addInput:input];
}
/****************AVCaptureDeviceInput****************/
/****************AVCaptureVideoDataOutput****************/
AVCaptureMetadataOutput *outPut = [[AVCaptureMetadataOutput alloc] init];
[outPut setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
outPut.rectOfInterest = self.transparentRect;
if ([self.captureSession canAddOutput:outPut]) {
[self.captureSession addOutput:outPut];
}
NSMutableArray *availableTypes = [[outPut availableMetadataObjectTypes] mutableCopy];
if ([availableTypes containsObject:AVMetadataObjectTypeQRCode]) {
[availableTypes removeObject:AVMetadataObjectTypeQRCode];
}
outPut.metadataObjectTypes = availableTypes;
/****************AVCaptureVideoDataOutput****************/
/****************AVCaptureVideoPreviewLayer****************/
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
previewLayer.frame = self.view.bounds;
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer insertSublayer:previewLayer atIndex:0];
/****************AVCaptureVideoPreviewLayer****************/
}
細看真的是沒有什麼大問題 ,但是再查看各種資料後 發現在rectOfInterest處設置是有很大問題的。
先看官方介紹
/*!
@property rectOfInterest
@abstract
Specifies a rectangle of interest for limiting the search area for visual metadata.
@discussion
The value of this property is a CGRect that determines the receiver's rectangle of interest for each frame of video.
The rectangle's origin is top left and is relative to the coordinate space of the device providing the metadata. Specifying
a rectOfInterest may improve detection performance for certain types of metadata. The default value of this property is the
value CGRectMake(0, 0, 1, 1). Metadata objects whose bounds do not intersect with the rectOfInterest will not be returned.
*/
@property(nonatomic) CGRect rectOfInterest NS_AVAILABLE_IOS(7_0);
這是設置一個興趣點 CGRect類型。但是賦值的過程中,得注意得這麼賦值CGSize size = self.view.bounds.size;
CGRect cropRect = <span style="font-family: Arial, Helvetica, sans-serif;">self.transparentRect;</span>
captureOutput.rectOfInterest = CGRectMake(cropRect.origin.x/size.width,
cropRect.origin.y/size.height,
cropRect.size.width/size.width,
cropRect.size.height/size.height);
在該文章中點擊打開鏈接
最後優化的代碼如下
CGSize size = self.view.bounds.size;
CGRect cropRect = CGRectMake(40, 100, 240, 240);
CGFloat p1 = size.height/size.width;
CGFloat p2 = 1920./1080.; //使用了1080p的圖像輸出
if (p1 < p2) {
CGFloat fixHeight = bounds.size.width * 1920. / 1080.;
CGFloat fixPadding = (fixHeight - size.height)/2;
captureOutput.rectOfInterest = CGRectMake((cropRect.origin.y + fixPadding)/fixHeight,
cropRect.origin.x/size.width,
cropRect.size.height/fixHeight,
cropRect.size.width/size.width);
} else {
CGFloat fixWidth = bounds.size.height * 1080. / 1920.;
CGFloat fixPadding = (fixWidth - size.width)/2;
captureOutput.rectOfInterest = CGRectMake(cropRect.origin.y/size.height,
(cropRect.origin.x + fixPadding)/fixWidth,
cropRect.size.height/size.height,
cropRect.size.width/fixWidth);
}
經測試,完成預期的掃描加識別..