最近需要用到二维码的扫描,发现苹果有自己的原生的api,这里简单介绍一下.
首先需要引入AVFoundation.framework库
在相应的viewController里边引入头文件.
#import<AVFoundation/AVFoundation.h>
//遵守代理
@interfaceScanViewController()<AVCaptureMetadataOutputObjectsDelegate>
@property(nonatomic,strong)AVCaptureSession*captureSession;//输入输出的中间桥梁
@end
接下来就是进行二维码的扫描
#pragma mark -开始扫描
/**
*开始扫描
*/
- (void)beginScanning
{
//获取摄像设备
AVCaptureDevice*device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput* input = [AVCaptureDeviceInputdeviceInputWithDevice:deviceerror:nil];
if(!input)
return;
//创建输出流
AVCaptureMetadataOutput* output = [[AVCaptureMetadataOutputalloc]init];
//设置代理在主线程里刷新
[outputsetMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];
//设置有效扫描区域
output.rectOfInterest= CGRectMake(0,0.5,1,1);
//初始化链接对象
self.session= [[AVCaptureSessionalloc]init];
//高质量采集率
[self.sessionsetSessionPreset:AVCaptureSessionPresetHigh];
[self.sessionaddInput:input];
[self.sessionaddOutput:output];
//设置扫码支持的编码格式(如下设置条形码和二维码兼容)
output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code];
AVCaptureVideoPreviewLayer*layer = [AVCaptureVideoPreviewLayerlayerWithSession:self.session];
layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
layer.frame=self.view.layer.bounds;
[self.view.layerinsertSublayer:layeratIndex:0];
//开始捕获
[self.sessionstartRunning];
}
/**
*扫描的输出结果
*
* @param metadataObjects扫描到的数据
*/
-(void)captureOutput:(AVCaptureOutput*)captureOutput didOutputMetadataObjects:(NSArray*)metadataObjects fromConnection:(AVCaptureConnection*)connection
{
if(metadataObjects.count>0) {
[self.sessionstopRunning];
AVMetadataMachineReadableCodeObject*metadataObject = [metadataObjectsobjectAtIndex:0];
UIAlertView*alert = [[UIAlertViewalloc]initWithTitle:@"扫描结果"message:metadataObject.stringValuedelegate:selfcancelButtonTitle:@"退出"otherButtonTitles:@"再次扫描",nil];
[alertshow];
}
}
- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex ==0) {
[self.navigationControllerpopViewControllerAnimated:YES];
}elseif(buttonIndex ==1) {
[self.sessionstartRunning];
}
}
另一个就是扫描相册里边的图片二维码 当点击从相册选取时掉用以下方法
if([UIImagePickerControllerisSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
// 1.初始化相册拾取器
UIImagePickerController*controller = [[UIImagePickerControlleralloc]init];
// 2.设置代理
controller.delegate=self;
// 3.设置资源:
controller.sourceType=UIImagePickerControllerSourceTypeSavedPhotosAlbum;
controller.modalTransitionStyle=UIModalTransitionStyleCoverVertical;
[selfpresentViewController:controlleranimated:YEScompletion:NULL];
}else{
UIAlertView* alert = [[UIAlertViewalloc]initWithTitle:@"提示"message:@"设备不支持访问相册,请在设置->隐私->照片中进行设置!"delegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil,nil];
[alertshow];
}
/**
*从相册选取图片监听
*/
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
//1.获取选择的图片
UIImage*image = info[UIImagePickerControllerOriginalImage];
//2.初始化一个监测器
CIDetector*detector = [CIDetectordetectorOfType:CIDetectorTypeQRCodecontext:niloptions:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
[pickerdismissViewControllerAnimated:YEScompletion:^{
//监测到的结果数组
NSArray*features = [detectorfeaturesInImage:[CIImageimageWithCGImage:image.CGImage]];
if(features.count>0) {
/**结果对象*/
CIQRCodeFeature*feature = [featuresobjectAtIndex:0];
NSString*scannedResult = feature.messageString;
UIAlertView* alertView = [[UIAlertViewalloc]initWithTitle:@"扫描结果"message:scannedResultdelegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil,nil];
[alertViewshow];
}
else{
UIAlertView* alertView = [[UIAlertViewalloc]initWithTitle:@"提示"message:@"该图片没有包含一个二维码!"delegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil,nil];
[alertViewshow];
}
}];
}
AVCaptureMetadataOutput类中有一个这样的属性(在IOS7.0之后可用):
@property(nonatomic)CGRectrectOfInterest;
这个属性大致意思就是告诉系统它需要注意的区域,大部分APP的扫码UI中都会有一个框,提醒你将条形码放入那个区域,这个属性的作用就在这里,它可以设置一个范围,只处理在这个范围内捕获到的图像的信息。在使用这个属性的时候。需要几点注意:
1、这个CGRect参数和普通的Rect范围不太一样,它的四个值的范围都是0-1,表示比例。
2、经过测试发现,这个参数里面的x对应的恰恰是距离左上角的垂直距离,y对应的是距离左上角的水平距离。
3、宽度和高度设置的情况也是类似。
3、举个例子如果我们想让扫描的处理区域是屏幕的下半部分,我们这样设置
?
转自:/liu_esther/article/details/51063171