条形d码扫描之rectOfInterest

今天因为需要写一个扫描条形码的功能,想着写一个这样的功能会很快,结果发现在代理

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 = self.transparentRect;
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);
}

经测试,完成预期的扫描加识别..

你可能感兴趣的:(程序开发,iOS扫描,二维码识别,条形码识别)