iOS_相機掃描二維碼、條形碼
阿新 • • 發佈:2019-02-02
媒體採集的幾個東西。這裡所需要明白的是,在這個流程中,這裡會存在幾個物件:
- 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