概述
- 通過某種特定的幾何圖形按一定規律在平面(二維方向上)分布的黑白相間的圖形記錄數據符號信息的
- 二維碼通常可以包含以下內容
- 純文本
- 名片
- URL
- 二維碼具有非常廣泛的應用
- 二維碼名片
- 掃碼付款
- 網址(URL),掃描后自動打開網址
二維碼的生成
-
生成原理
- 通過一個類CIFilter(濾鏡)包含二維碼中所有的信息,然后生成一張二維碼圖片
- 二維碼中間的icon(頭像),是通過在生成的圖片上添加一張圖片實現的
-
生成步驟
- 創建濾鏡
- 初始化濾鏡
- 添加二維碼信息
- 獲取生成的二維碼圖片
- 將二維碼圖片展示出來
-
生成的二維碼的效果圖
-
具體代碼實現
-
通過storyboard創建兩個imageView,分別用來展示二維碼圖片和頭像
-
擁有展示二維碼圖片的imageView
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
-
生成二維碼
/**點擊屏幕的時候顯示二維碼*/ - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //1.創建濾鏡 CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; //2.恢復默認 [filter setDefaults]; //3.給濾鏡添加數據 NSString *dataString = @"http://www.cnblogs.com/theDesertIslandOutOfTheWorld/"; // NSString *dataString = @"世俗孤島"; //將數據轉換成NSData類型 NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding]; //通過KVC設置濾鏡的二維碼輸入信息 [filter setValue:data forKey:@"inputMessage"]; //4.獲取輸出的二維碼圖片(CIImage類型) CIImage *outImage = [filter outputImage]; //將CIImage類型的圖片裝換成UIImage類型的圖片 UIImage *image = [UIImage imageWithCIImage:outImage]; //5.顯示二維碼圖片 self.imageView.image = image; }
-
通過二維碼掃描工具,可以掃描生成的二維碼
- 若二維碼的輸入信息是URL,則會打開指定的網絡資源
-
二維碼的掃描
- 注意:
- 二維碼掃碼需要使用攝像頭,需要真機設備
- Xcode7可是免費真機調試
- 二維碼掃描的過程
- 通過攝像頭掃描二維碼
- 解析二維碼數據
- 根據二維碼信息執行相應的操作
- 過程分析
- 通過攝像頭掃描二維碼信息需要用到AVCaptureSession類
- 該類是用來協調從音頻/視頻輸入端口到輸出端的數據
- 該類需要一個輸入設備AVCaptureDeviceInput,通常是攝像頭
- 該類需要一個輸出端,輸出指定類型的數據,有多個類可以選擇(如:AVCaptureMetadataOutput)
- 需要調用- startRunning方法開啟輸入源
- 通過AVCaptureSession類捕獲的數據,可以通過指定輸出端的過濾類型來以特定的類型解析捕獲的數據
- 可以為輸出端AVCaptureMetadataOutput設置代理,來聽捕獲過程
- 通過AVCaptureVideoPreviewLayer類將獲取的原始數據渲染到指定的圖層
- 通過攝像頭掃描二維碼信息需要用到AVCaptureSession類
- 二維碼的生成過程
-
通過成員屬性保存輸入源與輸出端的協調者(AVCaptureSession對象)
@property (nonatomic, weak) AVCaptureSession *session;
-
通過成員屬性保存展示通過輸入設備輸入的元數據的圖層,用於在適當的時候移除圖層
@property (nonatomic, weak) AVCaptureVideoPreviewLayer *layer;
-
創建AVCaptureSession類的對象(簡稱:捕獲對象),用於捕獲音頻/視頻端口的數據
AVCaptureSession *session = [[AVCaptureSession alloc] init]; self.session = session;
-
給捕獲對象添加輸入設備(通常是攝像頭)
//設置輸入設備輸入數據的類型(視頻) AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil]; [session addInput:input];
-
給捕獲對象添加輸出端
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; //設置代理 [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; [session addOutput:output];
-
設置輸入源的過濾條件(只獲取二維碼信息)
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
-
將捕獲的原始數據顯示到控制器的view上
AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:session]; layer.frame = self.view.bounds; [self.view.layer addSublayer:layer];
-
開始獲取數據
[session startRunning];
-
實現輸出端的代理方法,監聽捕獲過程
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { if (metadataObjects.count > 0) { //獲取輸出端的信息 AVMetadataMachineReadableCodeObject *object = [metadataObjects lastObject]; NSLog(@"%@", object.stringValue); //停止掃描 [self.session stopRunning]; //將展示圖層移除 [self.layer removeFromSuperlayer]; } else { NSLog(@"沒有掃描到數據"); } }
-