標籤:
偶爾用這一塊的東西,總是記不住,所以寫了兩個demo 注釋寫的非常詳細.
二維碼的產生:
#import "ViewController.h"#import <CoreImage/CoreImage.h>@interface ViewController ()@property (weak, nonatomic) IBOutlet UIImageView *codeImage;@end/* 1. 產生二維碼 要匯入CoreImage 這個系統原生架構 (因為要去擷取內建濾鏡 支援各種種類的二維碼) 2. ( inputMessage, 連結的字串 (輸入的 就是咱們自己去設定的) inputCorrectionLevel 連結類型 ) 3. 要記住 掃二維碼 是一個操作 根據得到的這個字串的類型 去讓他去做下一步的操作. 4.filter.outputImage 得到圖片 5.調整清晰度 */@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // 1. 建立濾鏡對象 內建濾鏡 支援各種種類的二維碼 跟一個類型 具體什麼格式 不清楚 // 通過一個分類的屬性 來進行列印 列印所有的對象 // NSLog(@"%@",[CIFilter filterNamesInCategory:kCICategoryBuiltIn]); // 二維碼濾鏡已經擷取 CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; // 2. 設定預設值 [filter setDefaults]; // 3.輸入字串 NSLog(@"%@",filter.inputKeys); // 完全可以吧這個字串去看做是一個特殊的字串類型 // 唯讀屬性 利用KVC 進行複製 // CIQRCodeGenerator filter requires NSData for inputMessage 這個哥們必須是一個二維碼 // 將字串 轉換成2進位的方法 [filter setValue:[@"http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html" dataUsingEncoding:NSUTF8StringEncoding] forKey:@"inputMessage"]; NSLog(@"%@",filter.inputKeys); // 5.放大圖片 CIImage 是繼承自NSObject (原因:CIImage 確實是放大了五倍,然後CodeImageFrame沒有改變,像素點密集 變得清晰) CIImage *resultImage = [filter.outputImage imageByApplyingTransform:CGAffineTransformMakeScale(5, 5)]; self.codeImage.image = [UIImage imageWithCIImage:resultImage]; // // 4.擷取二維碼的圖片// CIImage *imageC = filter.outputImage;// // self.codeImage.image = [UIImage imageWithCIImage:imageC];// }@end
二維碼的讀取:
#import "ViewController.h"#import <AVFoundation/AVFoundation.h>@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>@property (nonatomic,strong)AVCaptureSession *session;@property (nonatomic,strong)AVCaptureDeviceInput *input;@property (nonatomic,strong)AVCaptureMetadataOutput *output;// 建立預覽視圖 layer層 專門用來顯示輸入裝置來捕捉到的畫面@property (nonatomic,strong)AVCaptureVideoPreviewLayer *viewLayer; // 繼承自CALayer@end/* 1.匯入AVFoundtation 架構 輸入裝置 相機 麥克 鍵盤等 AVCaptureDeviceInput(子類) AVCaptureInput(父類) 輸出裝置 解析 (中繼資料) AVCaptureMetadataOutput -> AVCaptureOutput 會話連結 將輸入裝置和輸出裝置去建立聯絡 二維碼的掃碼和螢幕顯示的東西都是沒有關係的,只是和網路攝影機對準的二維碼有關 至於後來的頁面跳轉和別的操作 就是其他的商務邏輯 咱們只是拿到資料之後 對這個字串去進行分析 格式 中繼資料: 中繼資料(MetaData) 因為它們是用來描述具體資料/資訊的資料/資訊。 在日常生活中,中繼資料無所不在。有一類事物,就可以定義一套中繼資料。 中繼資料最大的好處是,它使資訊的描述和分類可以實現格式化,從而為機器處理創造了可能。 1. 建立輸入裝置對象 AVCaptureDeviceInput 並且設定好裝置類型 2,建立輸出裝置對象 AVCaptureMetadataOutput (中繼資料對象) 3. 建立 AVCaptureSession 對象 將輸入輸出(添加)建立聯絡 4. 設定視頻範圍 [self.session setSessionPreset:AVCaptureSessionPresetHigh]; 5.開啟 6,設定 AVCaptureMetadataOutput 的資料 並擷取對象.. ( 7. 設定輸出裝置的類型 (注意 有坑) *//* 輸出裝置的與資料得到可用參數 ( "org.iso.Aztec", "org.iso.Code128", "org.iso.Code39", "org.iso.Code39Mod43", "com.intermec.Code93", "org.iso.DataMatrix", "org.gs1.EAN-13", "org.gs1.EAN-8", "org.ansi.Interleaved2of5", "org.gs1.ITF14", "org.iso.PDF417", "org.iso.QRCode", 二維碼 類型 "org.gs1.UPC-E", face ) */@implementation ViewController- (void)viewDidLoad { [super viewDidLoad];}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ // 1 建立輸入裝置 (類型為相機) // 給定一個裝置 讓咱們知道是哪個裝置 AVMediaTypeVideo 就是這個樣式的的字串 ?? // 中繼資料 AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; self.input = [[AVCaptureDeviceInput alloc]initWithDevice:device error:nil]; // 2, 建立輸出裝置 用來去解析 self.output = [[AVCaptureMetadataOutput alloc]init]; // ?? // 2,1 設定輸出裝置的代理 (這個地方的代理設定的地放比較特殊) // 這個地方為什麼要去設定一個全域隊列 [ self.output setMetadataObjectsDelegate:self queue:dispatch_get_global_queue(0, 0)]; // //6. 設定中繼資料類型區別的// // 先去列印一下可用類型有哪些 (7.0 之前 和7.0 之後 這個地方是有)// NSLog(@"%@",self.output.metadataObjectTypes); // 中繼資料可以利用的資料類型// // 3. 建立會話層 建立聯絡 self.session = [[AVCaptureSession alloc]init]; // 3.1 先判斷能否添加 裝置 然後添加 if ([self.session canAddInput:self.input]) { [self.session addInput:self.input]; } if ([self.session canAddOutput:self.output]) { [self.session addOutput:self.output]; } // 5, 設定視頻範圍 //[self.session setSessionPreset:AVCaptureSessionPresetHigh]; // high 是自適應的 [self.session setSessionPreset:AVCaptureSessionPresetHigh]; //6. 設定中繼資料類型 // 先去列印一下可用類型有哪些 NSLog(@"%@",self.output.availableMetadataObjectTypes); // 中繼資料可以利用的資料類型 // 根據類型去進行設定 [self.output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]; // 4. 開啟會話 [self.session startRunning]; // 8. 增加一個預覽視圖 用來去顯示輸入裝置的畫面 // 建立 self.viewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session]; // 設定frame self.viewLayer.frame = self.view.bounds; // [self.view addSubview:self.viewLayer]; 繼承自CALayer [self.view.layer addSublayer:self.viewLayer]; }#pragma mark -- 代理的方法 解析資料的時候就會去調用這個方法// 資料解析完成之後 會給你返回一個字串- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ // 掃描的資料全部都放在 metadataObjects 既然是數組 那麼久先去列印他 //NSLog(@"%@",metadataObjects); //取出掃描的資料 AVMetadataMachineReadableCodeObject *objc = [metadataObjects firstObject]; NSLog(@"%@",objc.stringValue); // 關閉會話 [self.session stopRunning]; // 移除這個層 [self.viewLayer removeFromSuperlayer];}@end
二維碼產生與掃描