1. 程式人生 > >iOS_相機掃描二維碼、條形碼

iOS_相機掃描二維碼、條形碼

媒體採集的幾個東西。這裡所需要明白的是,在這個流程中,這裡會存在幾個物件:
- AVCaptureDevice。這裡代表抽象的硬體裝置。
- AVCaptureInput。這裡代表輸入裝置(可以是它的子類),它配置抽象硬體裝置的ports。
- AVCaptureOutput。它代表輸出資料,管理著輸出到一個movie或者影象。
- AVCaptureSession。它是input和output的橋樑。它協調著intput到output的資料傳輸。

  • 匯入框架、遵循協議
#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

這裡寫圖片描述