重点
1、它是横屏情况下的frame所以宽高和XY值需反向操作。就是按照竖屏模式应该将原先是XYWH要改为YXHW来设置;
2.设置相机和相册权限
NSCameraUsageDescription (相机权限访问)
NSPhotoLibraryUsageDescription (相册权限访问);
3.根据二维码或条形码格式不一样,设置支持的码流样式;
4.扫描到结果后需要停止扫描,不然会持续回到扫描结果;
代码:
//
- (void)instanceDevice
{
_isBarCode = YES;
self.scanBoxheight = self.scanBoxWidth = 200;
if (_isBarCode) {
self.scanBoxheight = 60;
self.scanBoxWidth = DeviceMaxWidth-20;
}
// //添加一个背景图片
CGRect mImagerect = CGRectMake((DeviceMaxWidth-self.scanBoxWidth)/2.0, (DeviceMaxHeight-self.scanBoxheight)/2, self.scanBoxWidth, self.scanBoxheight);
// [scanZomeBack setFrame:mImagerect];
CGRectscanCrop=[selfgetScanCrop:mImagerectreaderViewBounds:self.frame];
// [self addSubview:scanZomeBack];
//获取摄像设备
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
//创建输出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
//设置代理 在主线程里刷新
[outputsetMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
output.rectOfInterest= scanCrop;
//初始化链接对象
session = [[AVCaptureSession alloc]init];
//高质量采集率
[session setSessionPreset:AVCaptureSessionPresetHigh];
if(input) {
[sessionaddInput:input];
}
if(output) {
[sessionaddOutput:output];
//设置扫码支持的编码格式(如下设置条形码和二维码兼容)
NSMutableArray *a = [[NSMutableArray alloc] init];
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeQRCode]) {
[aaddObject:AVMetadataObjectTypeQRCode];
}
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeEAN13Code]) {
[aaddObject:AVMetadataObjectTypeEAN13Code];
}
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeEAN8Code]) {
[aaddObject:AVMetadataObjectTypeEAN8Code];
}
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeCode128Code]) {
[aaddObject:AVMetadataObjectTypeCode128Code];
}
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypePDF417Code]) {
[aaddObject:AVMetadataObjectTypePDF417Code];
}
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeUPCECode]) {
[aaddObject:AVMetadataObjectTypeUPCECode];
}
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeCode39Code]) {
[aaddObject:AVMetadataObjectTypeCode39Code];
}
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeCode93Code]) {
[aaddObject:AVMetadataObjectTypeCode93Code];
}
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeCode39Mod43Code]) {
[aaddObject:AVMetadataObjectTypeCode39Mod43Code];
}
output.metadataObjectTypes=a;
}
AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
layer.frame=self.layer.bounds;
[self.layer insertSublayer:layer atIndex:0];
[self setOverlayPickerView:self];
//开始捕获
[session startRunning];
}
//设置扫描线动画
-(void)loopDrawLine
{
_is_AnmotionFinished = NO;
CGRect rect = CGRectMake((DeviceMaxWidth-self.scanBoxWidth)/2.0, (DeviceMaxHeight-self.scanBoxheight)/2.0-10, self.scanBoxWidth, 2);
if (_readLineView) {
_readLineView.alpha = 1;
_readLineView.frame= rect;
}
else{
_readLineView= [[UIImageViewalloc]initWithFrame:rect];
[_readLineView setImage:[UIImage imageNamed:@"zbarscanline1"]];
[self addSubview:_readLineView];
}
[UIView animateWithDuration:1.5 animations:^{
//修改fream的代码写在这里
_readLineView.frame =CGRectMake((DeviceMaxWidth-self.scanBoxWidth)/2.0, CGRectGetMaxY(rect)+self.scanBoxheight, self.scanBoxWidth, 2);
}completion:^(BOOLfinished) {
if(!_is_Anmotion) {
[selfloopDrawLine];
}
_is_AnmotionFinished = YES;
}];
}
#pragma mark 二维码扫描框
- (void)setOverlayPickerView:(QRCodeReaderView*)reader
{
UIView*overlayView = [[UIViewalloc]initWithFrame:CGRectMake(0,64,kScreenWidth,kScreenHeight)];
overlayView.backgroundColor= [UIColorclearColor];
UIView*focusRect = [[UIViewalloc]initWithFrame:CGRectMake((DeviceMaxWidth-self.scanBoxWidth)/2.0, (kScreenHeight-self.scanBoxheight) /2.0-20-50,self.scanBoxWidth,self.scanBoxheight)];
focusRect.backgroundColor = [UIColor clearColor];
[overlayViewaddSubview:focusRect];
UIImageView *lefttop=[[UIImageView alloc]initWithFrame:CGRectMake(0,0,20,20)];
lefttop.image=[UIImage imageNamed:@"QRCodeCorner_LeftTop.png"];
[focusRectaddSubview:lefttop];
UIImageView*righttop=[[UIImageViewalloc]initWithFrame:CGRectMake(focusRect.frame.size.width-20,0,20,20)];
righttop.image=[UIImage imageNamed:@"QRCodeCorner_RightTop.png"];
[focusRectaddSubview:righttop];
UIImageView*leftbottom=[[UIImageViewalloc]initWithFrame:CGRectMake(0,focusRect.frame.size.height-20,20,20)];
leftbottom.image=[UIImage imageNamed:@"QRCodeCorner_LeftButtom.png"];
[focusRectaddSubview:leftbottom];
UIImageView*rightbottom=[[UIImageViewalloc]initWithFrame:CGRectMake(focusRect.frame.size.width-20,focusRect.frame.size.height-20,20,20)];
rightbottom.image=[UIImage imageNamed:@"QRCodeCorner_RightButtom.png"];
[focusRectaddSubview:rightbottom];
UIView*focusRectTop = [[UIViewalloc]initWithFrame:CGRectMake(0,0,kScreenWidth,focusRect.frame.origin.y)];
focusRectTop.backgroundColor= [UIColorblackColor];
focusRectTop.alpha=0.7;
[overlayViewaddSubview:focusRectTop];
UIView*focusRectLeft = [[UIViewalloc]initWithFrame:CGRectMake(0,focusRect.frame.origin.y,focusRect.frame.origin.x, focusRect.frame.size.height)];
focusRectLeft.backgroundColor= [UIColorblackColor];
focusRectLeft.alpha=0.7;
[overlayViewaddSubview:focusRectLeft];
UIView*focusRectRight = [[UIViewalloc]initWithFrame:CGRectMake(CGRectGetMaxX(focusRect.frame),focusRect.frame.origin.y,focusRect.frame.origin.x, focusRect.frame.size.height)];
focusRectRight.backgroundColor= [UIColorblackColor];
focusRectRight.alpha=0.7;
[overlayViewaddSubview:focusRectRight];
UIView*focusRectBottom = [[UIViewalloc]initWithFrame:CGRectMake(0,CGRectGetMaxY(focusRectRight.frame),kScreenWidth,kScreenHeight-CGRectGetMaxY(focusRectRight.frame))];
focusRectBottom.backgroundColor= [UIColorblackColor];
focusRectBottom.alpha=0.7;
[overlayViewaddSubview:focusRectBottom];
UILabel*label = [[UILabelalloc]initWithFrame:CGRectMake(0,CGRectGetMaxY(focusRect.frame) +20,kScreenWidth,20)];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:14];
label.textColor= [UIColorwhiteColor];
label.numberOfLines=0;
label.textAlignment = NSTextAlignmentCenter;
label.text = @"将二维码/条码放人框内,即可扫描";
[overlayViewaddSubview:label];
[readeraddSubview:overlayView];
if (!_isHomeScan) {
UIButton *manualBtn = [UIButton buttonWithType:UIButtonTypeCustom];
manualBtn.frame=CGRectMake((DeviceMaxWidth-50*widthRate)/2,CGRectGetMaxY(focusRect.frame) +20+20,50*widthRate,50*widthRate);
[manualBtnsetTitle:@"手动添加"forState:UIControlStateNormal];
[manualBtn.titleLabel setFont:[UIFont boldSystemFontOfSize:14]];
[manualBtnsetTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[manualBtnaddTarget:self action:@selector(manualBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[overlayViewaddSubview:manualBtn];
}
}
#pragma mark 根据扫描框坐标确定实际扫描区域
-(CGRect)getScanCrop:(CGRect)rect readerViewBounds:(CGRect)readerViewBounds
{
CGFloatx,y,width,height;
// width = (CGFloat)(rect.size.height+10)/readerViewBounds.size.height;
//
// height = (CGFloat)(rect.size.width-50)/readerViewBounds.size.width;
//
// x = (1-width)/2;
// y = (1-height)/2;
x = (CGRectGetHeight(readerViewBounds)-CGRectGetHeight(rect))/2/CGRectGetHeight(readerViewBounds);
y = (CGRectGetWidth(readerViewBounds)-CGRectGetWidth(rect))/2/CGRectGetWidth(readerViewBounds);
width =CGRectGetHeight(rect)/CGRectGetHeight(readerViewBounds);
height =CGRectGetWidth(rect)/CGRectGetWidth(readerViewBounds);
returnCGRectMake(x, y, width, height);
}
- (void)start
{
[session startRunning];
}
- (void)stop
{
[session stopRunning];
}
#pragma mark - 扫描结果
- (void)captureOutput:(AVCaptureOutput*)captureOutput didOutputMetadataObjects:(NSArray*)metadataObjects fromConnection:(AVCaptureConnection*)connection
{
if(metadataObjects && metadataObjects.count>0) {
AVMetadataMachineReadableCodeObject* metadataObject = [metadataObjectsobjectAtIndex:0];
//输出扫描字符串
if(_delegate&& [_delegaterespondsToSelector:@selector(readerScanResult:)]) {
[_delegatereaderScanResult:metadataObject.stringValue];
}
NSLog(@"码流格式:%@\n码流内容:%@",metadataObject.type,metadataObject.stringValue);
[session stopRunning];//停止扫描
//播放扫描二维码的声音
SystemSoundID soundID;
NSString *strSoundFile = [[NSBundle mainBundle] pathForResource:@"noticeMusic" ofType:@"wav"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:strSoundFile],&soundID);
AudioServicesPlaySystemSound(soundID);
}
}
识别图片:
@property (strong, nonatomic) CIDetector *detector;
self.detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{ CIDetectorAccuracy : CIDetectorAccuracyHigh }];
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
if(!image){
image = [infoobjectForKey:UIImagePickerControllerOriginalImage];
}
readview.is_Anmotion = YES;
NSArray*features = [self.detectorfeaturesInImage:[CIImageimageWithCGImage:image.CGImage]];
if(features.count>=1) {
[pickerdismissViewControllerAnimated:YES completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
CIQRCodeFeature*feature = [featuresobjectAtIndex:0];
NSString*scannedResult = feature.messageString;
//播放扫描二维码的声音
SystemSoundIDsoundID;
NSString*strSoundFile = [[NSBundlemainBundle]pathForResource:@"noticeMusic"ofType:@"wav"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:strSoundFile],&soundID);
AudioServicesPlaySystemSound(soundID);
[selfaccordingQcode:scannedResult];
}];
}
else{
UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:@"目前仅支持发票二维码扫描" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
alertView.tag=1022;
[alertViewshow];
[pickerdismissViewControllerAnimated:YES completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
readview.is_Anmotion = NO;
[readviewstart];
}];
}
}