iOS_相机扫描二维码、条形码

媒体采集的几个东西。这里所需要明白的是,在这个流程中,这里会存在几个对象:
- AVCaptureDevice。这里代表抽象的硬件设备。
- AVCaptureInput。这里代表输入设备(可以是它的子类),它配置抽象硬件设备的ports。
- AVCaptureOutput。它代表输出数据,管理着输出到一个movie或者图像。
- AVCaptureSession。它是input和output的桥梁。它协调着intput到output的数据传输。


Swift对应功能实现


  • 导入框架、遵循协议
#import <AVFoundation/AVFoundation.h>
// 遵循协议
AVCaptureMetadataOutputObjectsDelegate
  • 判断相机的状态
AVAuthorizationStatus authorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    switch (authorizationStatus) {
        case AVAuthorizationStatusNotDetermined: {
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler: ^(BOOL granted) {
                if (granted) {
                    [self startCapture];
                } else {
                    [self alertMessage:@"访问受限"];
                }
            }];
            break;
        }
        case AVAuthorizationStatusAuthorized: {
            [self startCapture];
            break;
        }
        case AVAuthorizationStatusRestricted:
        case AVAuthorizationStatusDenied: {
            [self alertMessage:@"访问受限"];
            break;
        }
        default: {
            break;
        }
    }
  • 打开相机
 - (void)startCapture{
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error;
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
    if (deviceInput) {
        [session addInput:deviceInput];
        AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init];
        [metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        [session addOutput:metadataOutput]; // 这行代码要在设置 metadataObjectTypes 前
        metadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeEAN13Code]; // 设置识别图片类型
        AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        previewLayer.frame = self.view.frame;
        [self.view.layer insertSublayer:previewLayer atIndex:0];
        __weak typeof(self) weakSelf = self;
        [[NSNotificationCenter defaultCenter] addObserverForName:AVCaptureInputPortFormatDescriptionDidChangeNotification
                                                          object:nil
                                                           queue:[NSOperationQueue currentQueue]
                                                      usingBlock: ^(NSNotification *_Nonnull note) {
                                                          metadataOutput.rectOfInterest = [previewLayer metadataOutputRectOfInterestForRect:weakSelf.scanRect];
                                                          // 如果不设置,整个屏幕都可以扫
                                                      }];
        // 设置扫描界面布局
        QRScanView *scanView = [[QRScanView alloc] initWithScanRect:self.scanRect];
        [self.view addSubview:scanView];
        [session startRunning];
    } else {
        NSLog(@"%@", error);
        [self alertMessage:error.localizedDescription];
    }
}
  • 处理扫描到的图片
#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects.firstObject;
    // 成功后系统不会停止扫描,用isQRCodeCaptured变量来控制。
    if (self.isQRCodeCaptured == NO) {
        self.isQRCodeCaptured = YES;
        NSString *decodeMessage = @"未扫描到二维码、条形码";
        if ([metadataObject.type isEqualToString:AVMetadataObjectTypeQRCode]) {
            // 二维码
            decodeMessage = metadataObject.stringValue;
        }else if ([metadataObject.type isEqualToString:AVMetadataObjectTypeCode128Code]){
            // 条形码
            decodeMessage = metadataObject.stringValue;
        }else if ([metadataObject.type isEqualToString:AVMetadataObjectTypeEAN13Code]){
            // ISBN书号条码、EAN13码
            decodeMessage = metadataObject.stringValue;
        }
        NSLog(@"%@",decodeMessage);
    }
}

AVCaptureMetadataOutput:
相机扫描结果种类
metadataObjectTypes:
// 二维码
AVMetadataObjectTypeQRCode
// 条形码
// Code128
AVMetadataObjectTypeCode128Code
// Code39
AVMetadataObjectTypeCode39Code
// Code39Mod43
AVMetadataObjectTypeCode39Mod43Code
// Code93
AVMetadataObjectTypeCode93Code
// UPC-E商品条码
AVMetadataObjectTypeUPCECode
// EAN-13商品条码/UPC-A商品条码/ISBN书号条码
AVMetadataObjectTypeEAN13Code
// EAN-8商品条码
AVMetadataObjectTypeEAN8Code
// PDF417
AVMetadataObjectTypePDF417Code
// 交叉25码
AVMetadataObjectTypeInterleaved2of5Code
// ITF14
AVMetadataObjectTypeITF14Code
// Aztec
AVMetadataObjectTypeAztecCode
// 数据矩阵
AVMetadataObjectTypeDataMatrixCode

这里写图片描述


代码地址:
https://github.com/FlyingKuiKui/BarCodeAndQRCode.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值