最近在研究ios的二维码扫描功能,网上有好多诸如ZXing,ZBar第三方类库的介绍,如果仅仅是为了扫码,我觉得使用第三方类库有些麻烦,其实ios提供了二维码扫描的api,不多说了,直接上代码
//
// ViewController.m
// Quickmark
//
// Created by chengpengfei on 15/10/22.
// Copyright © 2015年 LIONTECH TECHNOLOGY CO.,LTD. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "CJMScanController.h"
#import "LTBottomView.h"
@interface CJMScanController ()<AVCaptureMetadataOutputObjectsDelegate>
@property ( strong , nonatomic ) AVCaptureDevice * device;
@property ( strong , nonatomic ) AVCaptureDeviceInput * input;
@property ( strong , nonatomic ) AVCaptureMetadataOutput * output;
@property ( strong , nonatomic ) AVCaptureSession * session;
@property ( strong , nonatomic ) AVCaptureVideoPreviewLayer * preview;
@end
@implementation CJMScanController
@synthesize session;
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UINavigationBar *bar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,64)];
bar.barTintColor = [UIColor yellowColor];
UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"扫描二维码"];
[bar pushNavigationItem:navigationItem animated:YES];
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStyleDonetarget:self action:@selector(cancleScan)];
navigationItem.rightBarButtonItem = rightItem;
[self.view addSubview:bar];
// Do any additional setup after loading the view, typically from a nib.
//获取摄像设备
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
//创建输出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
//设置代理 在主线程里刷新
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//初始化链接对象
session = [[AVCaptureSession alloc]init];
//高质量采集率
[session setSessionPreset:AVCaptureSessionPresetHigh];
[session addInput:input];
[session addOutput:output];
//设置扫码支持的编码格式(如下设置条形码和二维码兼容)
output.metadataObjectTypes=@[AVMetadataObjectTypeAztecCode,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeCode39Code,AVMetadataObjectTypeCode39Mod43Code,AVMetadataObjectTypeCode93Code,AVMetadataObjectTypeDataMatrixCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeFace,AVMetadataObjectTypeInterleaved2of5Code,AVMetadataObjectTypeITF14Code,AVMetadataObjectTypePDF417Code,AVMetadataObjectTypeQRCode,AVMetadataObjectTypeUPCECode];
CGFloat width = [UIScreen mainScreen].bounds.size.width;
CGFloat height = [UIScreen mainScreen].bounds.size.height;
CGFloat w1 = 250/width;
CGFloat h1 = 250/height;
CGFloat w2 = (1-w1)/2;
CGFloat h2 = 64/height+(height-250-64)/(height*2);
output.rectOfInterest = CGRectMake(h2,w2, h1, w1);
LTBottomView*bView = [[LTBottomView alloc] initWithFrame:CGRectMake(0, 64, width, height-64)];
bView.backgroundColor = [UIColor clearColor];
bView.buttomColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.8];
bView.cutRect = CGRectMake((1-w2-w1)*width, h2*height-64, width*w1, height*h1);
[self.view addSubview:bView];
AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
layer.frame=CGRectMake(0, 0, width, height);
[self.view.layer insertSublayer:layer atIndex:0];
//开始捕获
[session startRunning];
}
-(void) cancleScan{
[self dismissViewControllerAnimated:YES completion:^{}];
}
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
NSString *stringValue;
if ([metadataObjects count ] > 0 )
{
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];
//输出扫描字符串
NSLog(@"%@",metadataObject.stringValue);
[session stopRunning];
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate scanFinished:self content:metadataObject.stringValue];
}];
}
}
-(void)viewWillAppear:(BOOL)animated {
if (!session.isRunning) {
[session startRunning];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
上面需要注意的是output.rectOfInterest的使用
output.rectOfInterest 是一个CGRect,即扫描区域,这个CGRect跟我们平常用的不同,我们平常使用CGRect一般使用CGRectMake(X,Y,W,H) X,Y,W,Z是任意值,但是在这里恰好反过来了
output.rectOfInterest = CGRectMake(Y,X,H,W);这里的Y,X,H,W是0-1的值,即比值,而且X,Y是以右上角为参考