iOS自带扫码实现以及扫码类型

  1 //

  2 //  SYTCodeScanerViewController.m

  3 //  SYTCodeScan

  4 //

  5 //  Created by iMac on 15/5/6.

  6 //  Copyright (c) 2015年 S.F. All rights reserved.

  7 //

  8 

  9 #import "SYTCodeScanerViewController.h"

 10 #import <AVFoundation/AVFoundation.h>

 11 

 12 @interface SYTCodeScanerViewController ()<AVCaptureMetadataOutputObjectsDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>

 13 

 14 @property (nonatomic ,strong) AVCaptureSession *captureSession;                 //捕捉会话

 15 @property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;    //预览图层layer

 16 @property (strong, nonatomic) UIView *boxView;                                  //扫描识别框

 17 

 18 @property (weak, nonatomic) IBOutlet UILabel *resoultLab;                       //结果显示Lab

 19 

 20 @property (weak, nonatomic) IBOutlet UIButton *scanImageButton;

 21 

 22 @property (nonatomic, strong) UIImagePickerController *imagePickerController;

 23 

 24 @end

 25 

 26 @implementation SYTCodeScanerViewController

 27 

 28 - (void)viewDidLoad {

 29     [super viewDidLoad];

 30     

 31     _captureSession = nil;

 32     

 33     [self startScan];

 34     

 35 }

 36 

 37 - (void)startScan

 38 {

 39     //初始化设备(摄像头)

 40     NSError *error = nil;

 41     AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

 42     

 43     //创建输入流

 44     AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];

 45     if (error)

 46     {

 47         NSLog(@"没有摄像头:%@", error.localizedDescription);

 48         return;

 49     }

 50     

 51     

 52     //创建输出流

 53     AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];

 54     

 55     //实例化捕捉会话并添加输入,输出流

 56     _captureSession = [[AVCaptureSession alloc] init];

 57     //高质量采集率

 58     [_captureSession setSessionPreset:AVCaptureSessionPresetHigh];

 59     

 60     [_captureSession addInput:input];

 61     [_captureSession addOutput:output];

 62     

 63     //设置输出的代理,在主线程里刷新

 64     [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];   //用串行队列新线程结果在UI上显示较慢

 65     

 66     //扫码类型

 67     [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode,         //二维码

 68                                      AVMetadataObjectTypeCode39Code,     //条形码   韵达和申通

 69                                      AVMetadataObjectTypeCode128Code,    //商品条码  顺丰用的

 70                                      AVMetadataObjectTypeCode39Mod43Code,

 71                                      AVMetadataObjectTypeEAN13Code,

 72                                      AVMetadataObjectTypeEAN8Code,

 73                                      AVMetadataObjectTypeCode93Code, //条形码,星号来表示起始符及终止符,如邮政EMS单上的条码

 74                                      AVMetadataObjectTypeUPCECode]];

 75     

 76     _videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];

 77     

 78     [_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

 79     

 80     //添加预览图层

 81     _videoPreviewLayer.frame = self.view.frame;

 82     [self.view.layer addSublayer:_videoPreviewLayer];

 83     [self.view bringSubviewToFront:self.view.subviews[0]];

 84 

 85     

 86     //扫描框

 87     

 88     _boxView = [[UIView alloc] initWithFrame:CGRectMake(60, 100, 200, 200)];

 89     _boxView.layer.borderColor = [UIColor greenColor].CGColor;

 90     _boxView.layer.borderWidth = 1.0f;

 91     [self.view addSubview:_boxView];

 92     

 93     //扫描识别范围

 94     output.rectOfInterest = CGRectMake(100 / self.view.bounds.size.height,

 95                                        60  / self.view.bounds.size.width,

 96                                        200 / self.view.bounds.size.height,

 97                                        200 / self.view.bounds.size.width);

 98     

 99     //开始扫描

100     [_captureSession startRunning];

101     

102     

103 }

104 

105 #pragma mark - 扫描结果代理方法

106 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection

107 {

108     [_captureSession stopRunning];

109 //    [_videoPreviewLayer removeFromSuperlayer];

110     

111     if (metadataObjects.count > 0) {

112         

113         AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];

114         

115         _resoultLab.text = obj.stringValue;

116         

117         NSLog(@"扫码扫描结果,obj.stringValue == %@", obj.stringValue);

118     }

119     

120 }

121 

122 

123 #pragma mark 选择照片

124 

125 #pragma -mark - UIImagePickerViewControllerDelegate

126 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

127 {

128     

129     NSLog(@"info == %@", info);

130     [self.imagePickerController dismissViewControllerAnimated:YES completion:nil];

131     

132     UIImage *image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];

133     

134     

135 }

136 

137 

138 - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker

139 {

140     [self.imagePickerController dismissViewControllerAnimated:YES completion:nil];

141 

142 }

143 

144 - (IBAction)photoPickBtn:(UIButton *)sender {

145     

146     if (!_imagePickerController) {

147         

148         _imagePickerController = [[UIImagePickerController alloc] init];

149         _imagePickerController.delegate =self;

150         _imagePickerController.SourceType = UIImagePickerControllerSourceTypePhotoLibrary;

151     }

152     

153     [self presentViewController:self.imagePickerController animated:YES completion:nil];

154 }

155 @end

 

首先,AVCaptureMetadataOutput类中有一个这样的属性(在IOS7.0之后可用):

@property(nonatomic) CGRect rectOfInterest;

  这个属性大致意思就是告诉系统它需要注意的区域,大部分APP的扫码UI中都会有一个框,提醒你将条形码放入那个区域,这个属性的作用就在这里,它可以设置一个范围,只处理在这个范围内捕获到的图像的信息。如此一来,可想而知,我们代码的效率又会得到很大的提高,在使用这个属性的时候。需要几点注意:

1、这个CGRect参数和普通的Rect范围不太一样,它的四个值的范围都是0-1,表示比例。

2、经过测试发现,这个参数里面的x对应的恰恰是距离左上角的垂直距离,y对应的是距离左上角的水平距离。

3、宽度和高度设置的情况也是类似。

3、举个例子如果我们想让扫描的处理区域是屏幕的下半部分,我们这样设置

output.rectOfInterest=CGRectMake(0.5,0,0.5, 1);

你可能感兴趣的:(ios)