#pragma mark - 開始掃描 - ( void )startScanning { // 1.建立輸入設備(攝像頭) AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil ]; // 2.建立輸入方式(Metadata) AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; [output setMetadataObjectsDelegate: self queue: dispatch_get_main_queue ()]; // 3.建立會話,將輸入和輸出聯繫起來 AVCaptureSession *session = [[AVCaptureSession alloc] init]; [session addInput:input]; [session addOutput:output]; [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]; // 4.建立會話圖層 AVCaptureVideoPreviewLayer *layer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; layer.frame = self .view.bounds; [ self .view.layer insertSublayer:layer atIndex:0]; self .layer = layer; // 5.開始掃描 [session startRunning]; // 6.設置掃描的區域 CGSize size = [ UIScreen mainScreen].bounds.size; CGFloat x = self .qrCodeView.frame.origin.y / size.height; CGFloat y = self .qrCodeView.frame.origin.x / size.width; CGFloat w = self .qrCodeView.frame.size.height / size.height; CGFloat h = self .qrCodeView.frame.size.width / size.width; output.rectOfInterest = CGRectMake (x, y, w, h); } - ( void )captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:( NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { // 0.移除以前的繪製 for ( CAShapeLayer *layer in self .layers) { [layer removeFromSuperlayer]; } // 1.獲取掃描結果 NSMutableString *resultMStr = [ NSMutableString string]; for (AVMetadataMachineReadableCodeObject *result in metadataObjects) { // 1.1.獲取掃描到的字符串 [resultMStr appendString:result.stringValue]; // 1.2.繪製掃描到內容的邊框 [ self drawEdgeBorder:result]; } // 2.顯示結果 NSString *string = [resultMStr isEqualToString: @"" ] ? @"請將二維碼放入輸入框中" : resultMStr; self .resultLabel.text = string; } - ( void )drawEdgeBorder:(AVMetadataMachineReadableCodeObject *)resultObjc { // 0.轉化object resultObjc = (AVMetadataMachineReadableCodeObject *)[ self .layer transformedMetadataObjectForMetadataObject:resultObjc]; // 1.建立繪製的圖層 CAShapeLayer *shapeLayer = [[ CAShapeLayer alloc] init]; // 2.設置圖層的屬性 shapeLayer.fillColor = [ UIColor clearColor]. CGColor ; shapeLayer.strokeColor = [ UIColor blueColor]. CGColor ; shapeLayer.lineWidth = 5; // 3.建立貝塞爾曲線 // 3.1.建立貝塞爾曲線 UIBezierPath *path = [[ UIBezierPath alloc] init]; // 3.2.將path移動到起始位置 int index = 0; for ( id dict in resultObjc.corners) { // 3.2.1.獲取點 CGPoint point = CGPointZero ; CGPointMakeWithDictionaryRepresentation (( CFDictionaryRef )dict, &point); // NSLog(@"%@", NSStringFromCGPoint(point)); // 3.2.2.判斷如何使用該點 if (index == 0) { [path moveToPoint:point]; } else { [path addLineToPoint:point]; } // 3.2.3.下標值自動加1 index++; } // 3.3.關閉路徑 [path closePath]; // 4.畫出路徑 shapeLayer.path = path. CGPath ; // 5.將layer添加到圖冊中 [ self .view.layer addSublayer:shapeLayer]; // 6.添加到數組中 [_layers addObject:shapeLayer]; } - ( NSMutableArray *)layers { if (_layers == nil ) { _layers = [ NSMutableArray array]; } return _layers; } |