ios-实现二维码扫描功能

在此就简单的介绍下二维码扫描功能的实现把

首先先说下思路,我们需要去配置的就是

  1、输入设备(用来获取外界信息),输入设备有摄像头、麦克风、键盘
  2、输出设备(将收集到的信息进行解析去获取收到的内容)
  3、会话的session(用来连接输入和输出的设备),不然的话你输入和输出设备都是独立的没有个连接
  4、展示输入设备所采集的信息

我们可以定义以下的属性

//1、输入设备(用来获取外界信息),输入设备有摄像头、麦克风、键盘
@property (nonatomic ,strong)AVCaptureDeviceInput *input;

//2、输出设备(将收集到的信息进行解析去获取收到的内容)
@property (nonatomic ,strong)AVCaptureMetadataOutput *output;

//3、会话的session(用来连接输入和输出的设备)
/**
 AVCaptureSession(捕捉会话管理):它从物理设备得到数据流(比如摄像头和麦克风),然后输出,它可以通过来控制捕捉数据的格式和质量
 */
@property (nonatomic ,strong)AVCaptureSession *session;

//4、展示输入设备所采集的信息,也就是被用于自动显示相机产生的实时图像
@property (nonatomic ,strong)AVCaptureVideoPreviewLayer *previewlayer;
之后就是进行创建操作

- (IBAction)ScanClick:(id)sender {
    
    //首先先判断输入设备是否可用,获取的是摄像头设备
    
    AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    if(device==nil)
    {
        //设置弹出alertController
        UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"设备没有摄像头" preferredStyle:
        UIAlertControllerStyleAlert];
       
        [alert addAction:[UIAlertAction actionWithTitle:@"确认" style: UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull
          action) {
            
        }]];
        [self presentViewController:alert animated:YES completion:nil];
        return;
    }
    
     //1、输入设备(用来获取外界信息)
    self.input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    
    //2、输出设备(将收集到的信息进行解析去获取收到的内容)
    self.output = [AVCaptureMetadataOutput new];
    
    //3、会话的session(用来连接输入和输出的设备)
    self.session = [AVCaptureSession new];
    
    //用于设置output输出流的bitrate或者说采集的质量
    if([self.session canSetSessionPreset:AVCaptureSessionPresetHigh])
    {
        [self.session setSessionPreset:AVCaptureSessionPresetHigh];
    }
    //捕捉会话管理和输入输出设备进行关联
    if([self.session canAddInput:self.input])
    {
        [self.session addInput:self.input];
    }
    if([self.session canAddOutput:self.output])
    {
        [self.session addOutput:self.output];
    }
    //指定输出设备的代理,用来接收返回的数据,回调在主队列中执行
    [self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    //设置元数据类型 二维码就是QRCode
    [self.output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
    
    //设置扫描区域的大小
    CGFloat Width = self.view.bounds.size.width;
    CGFloat Height =  self.view.bounds.size.height;
    
    [self.output setRectOfInterest:CGRectMake((Height*0.5 - 140)/Height,(Width * 0.5 - 140)/Width, 280/Height, 280/Width)];
    
    //4、特殊的layer(展示输入的设备所采集的信息),可被用于自动显示相机产生的实时图像
    self.previewlayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:_session];

    //设置layer的大小,
    self.previewlayer.frame = self.view.bounds;

    //添加layer
    [self.view.layer addSublayer:self.previewlayer];
     
    //启动会话
    [self.session startRunning];
   }

  //获取扫描的结果
-(void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects
 fromConnection:(AVCaptureConnection *)connection
{
    //1、停止会话
    [self.session stopRunning];
    
    //2、删除layer
    [self.previewlayer removeFromSuperlayer];
    
    //3、遍历数据获取内容
    for(AVMetadataMachineReadableCodeObject * obj in metadataObjects)
    {
        self.detailLabel.text = obj.stringValue;
    }
    //captureOutput: 输出设备的意思
    //metadataObjects: 元数据对象的数组
    //connection: 连接
    
}
    
这里需要注意的就是设置扫描区域的大小,它的默认扫描区域时全屏,默认值是(0,0,1,1)

如下图所示


如果我们要去设置扫描区域的大小也就是去设置setRectOfInterest,里面传入的CGRect的x和y和w和h都是0-1。

这里需要注意的是我们这里传入的应该的四个参数应该是Y,X,H,W,右上角是原点,如下图所示


这里还有一点需要介绍的是



这里传入的数组多加了个__kindof,__kindof:代表这个数组里面可以有它本身的类也可以有它的子类,也会被用在方法的返回值,加__kindof修饰后,比如说一个方法的返回值原本是NSArray,但是方法里边却返回了一个NSArray的子类NSMutableArray,也就是说,加__kindof修饰后,本类及其子类都可以返回,调用使用时也可以使用本类或者子类去接收方法的返回值。我们可以看到苹果对于下面这个方法来说,返回值也是加了__kindof

- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;

还有一点要补充的就是下面这个方法

+ (Class)layerClass
{
    return [AVCaptureVideoPreviewLayer class];
}
每一个UIView都有在一个CALayer,这个图层是由视图自动创建和管理的,一旦视图被创建,我们就无法去更改这个layer了。但是如果我们自定义一个view,那我们就可以重写+layerClass方法使得在创建的时候能返回一个不同的图层的子类。UIView会在初始化的时候调用+layerClass方法,然后用它的返回类型来创建view的layer。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值