前言
早上使用微信的時候,突然想到以前在專案中整合掃碼功能,當時沒有從相簿中掃描二維碼的需求,加上需要向下相容,於是選擇整合了zbar掃描。今天我們就來看一下如何實現從相簿中掃碼、以及原生掃描。
原生掃描
- iOS7之後,AVFoundation讓我們終於可以使用原生掃描進行掃碼了(二維碼與條碼皆可)AVFoundation可以讓我們從裝置中獲取到輸入流與輸出流,從而獲取二維碼中包含的資訊。
- 實現原生掃描非常簡單。
1.先匯入AVFoundation框架。
2.接著設定代理,實現代理回撥方法
AVCaptureMetadataOutputObjectsDelegate
3.然後建立幾個類即可:
裝置 AVCaptureDevice
捕捉會話 AVCaptureSession
輸入流 AVCaptureDeviceInput
輸出流 AVCaptureMetadataOutput
預覽圖層 AVCaptureVideoPreviewLayer - 下面是簡單的程式碼實現示例
1234567891011121314151617181920NSError *error = nil;AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];//裝置AVCaptureSession *session = [[AVCaptureSession alloc] init];//捕捉會話[session setSessionPreset:AVCaptureSessionPresetHigh];//設定採集率AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];//輸入流AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];//輸出流//新增到捕捉會話[session addInput:input];[session addOutput:output];//掃碼型別:需要先將輸出流新增到捕捉會話後再進行設定//這裡只設定了可掃描二維碼,有條碼需要,在陣列中繼續新增即可[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];//輸出流delegate,在主執行緒重新整理UI[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];AVCaptureVideoPreviewLayer *videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];//預覽videoPreviewLayer.frame = self.view.bounds;[self.view.layer insertSublayer:videoPreviewLayer atIndex:0];//新增預覽圖層//還可以設定掃描範圍 output.rectOfInterest 不設定預設為全屏//開始掃描[session startRunning]; - 接著實現掃碼成功的回撥方法
123456- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {NSString *content = @"";AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects.firstObject;content = metadataObject.stringValue;//獲取到二維碼中的資訊字串//對此字串進行處理(音效、網址分析、頁面跳轉等)} - 我們還可以新增掃碼成功後的聲音與振動效果,提高使用者體驗
123456- (void)playBeep{SystemSoundID soundID;AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"滴-2"ofType:@"mp3"]], &soundID);AudioServicesPlaySystemSound(soundID);AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);}
從相簿獲取二維碼
- iOS8之後,可以使用CIDetector(CIDetector可用於人臉識別)進行圖片解析,從而使我們可以便捷的從相簿中獲取到二維碼。
- 1.呼叫系統相簿,從系統相簿中選取圖片
2.使用探測器(CIDetector)對選取的圖片進行處理,取得圖片二維碼中包含的資料資訊。 - 下面是簡單的程式碼實現示例
1234567891011121314151617181920212223242526- (void)choicePhoto{//呼叫相簿UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;imagePicker.delegate = self;[self presentViewController:imagePicker animated:YES completion:nil];}//選中圖片的回撥-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{NSString *content = @"" ;//取出選中的圖片UIImage *pickImage = info[UIImagePickerControllerOriginalImage];NSData *imageData = UIImagePNGRepresentation(pickImage);CIImage *ciImage = [CIImage imageWithData:imageData];//建立探測器CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyLow}];NSArray *feature = [detector featuresInImage:ciImage];//取出探測到的資料for (CIQRCodeFeature *result in feature) {content = result.messageString;}//進行處理(音效、網址分析、頁面跳轉等)}
原始碼
點此下載:github原始碼
結語
原生掃描比zbar、zxing效率更高,且這兩個庫年久失修(zxingOBJC有人在持續維護)還有相容性問題。
CIDetector是系統為我們提供的非常強大的類庫,但是很多公司因為需要向下相容,所以沒有辦法使用。
如果專案不需向下相容多個版本時,建議使用系統原生掃描以及CIDetector進行二維碼相關處理。
參考:
http://www.tuicool.com/articles/ie2aAjv
http://www.jianshu.com/p/cc79c45b4ccf