iOS 二維碼學習過程

二維碼生成

生成二維碼需要導入CoreImage框架,通過濾鏡CIFilter生成二維碼。
二維碼的容錯
二維碼都有一定的糾錯,就是有部分污損或者破損都沒有關系,照常識別。但是也是有限度的
這根據生成時使用的糾錯級別而定,可以有7%~%30左右的損壞(大致),實際上保守一點更好。
基本原則:
1、三個角上的“回”及“回”字周圍的底色不要動
2、中間部分和不帶“回”字的一角是可以填圖片的(中間最好)
3、如果中間有小的“回”字,能不變就不變,能少變就少變
4、盡可能放大二維碼后再添加圖片,不要添加圖片后放大
5、生成時盡量選擇較高的糾錯級別

1、最原始的生成二維碼的步驟

代碼實現

 //1、創建過濾器
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    //2、恢復默認
    [filter setDefaults];
    //3、給過濾器添加數據
    NSString *dataString = @"你好,河南";
    NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    //4、通過KVO設置路徑InputMessage數據
    [filter setValue:data forKey:@"inputMessage"];
    //5、獲取輸出二維碼
    CIImage *outPutImage = [filter outputImage];
    //6、將CIImage轉換為UIImage
    _imageView.image = [UIImage imageWithCIImage:outPutImage];

效果圖
屏幕快照 2017-02-10 下午2.39.46.png

默認情況下生成的圖片比較模糊,所以需要我們重新繪制一下

2、清晰二維碼

 //二維碼過濾器
    CIFilter *qrImageFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    
    //設置過濾器默認屬性 (老油條)
    [qrImageFilter setDefaults];
    
    //將字符串轉換成 NSdata (雖然二維碼本質上是 字符串,但是這里需要轉換,不轉換就崩潰)
    NSData *qrImageData = [@"你看我帥不帥" dataUsingEncoding:NSUTF8StringEncoding];
    
    //我們可以打印,看過濾器的 輸入屬性.這樣我們才知道給誰賦值
    NSLog(@"%@",qrImageFilter.inputKeys);
    /*
     inputMessage,        //二維碼輸入信息
     inputCorrectionLevel //二維碼錯誤的等級,就是容錯率
     */
    
    
    //設置過濾器的 輸入值  ,KVC賦值
    [qrImageFilter setValue:qrImageData forKey:@"inputMessage"];
    
    //取出圖片
    CIImage *qrImage = [qrImageFilter outputImage];
    
    //但是圖片 發現有的小 (27,27),我們需要放大..我們進去CIImage 內部看屬性
    qrImage = [qrImage imageByApplyingTransform:CGAffineTransformMakeScale(9, 9)];
    
    
    self.imageView.image = [UIImage imageWithCIImage:qrImage];
    //    self.imageView.image = [UIImage imageWithCIImage:qrImage scale:100.0 orientation:UIImageOrientationUp];
    
    
    
    //    //如果還想加上陰影,就在ImageView的Layer上使用下面代碼添加陰影
    
    self.imageView.layer.shadowOffset=CGSizeMake(0, 5);//設置陰影的偏移量
    
    self.imageView.layer.shadowRadius=1;//設置陰影的半徑
    
    self.imageView.layer.shadowColor=[UIColor redColor].CGColor;//設置陰影的顏色為黑色
    
    self.imageView.layer.shadowOpacity=0.3;
效果圖
屏幕快照 2017-02-10 下午3.24.16.png

3、生成彩色二維碼

彩色二維碼,雖然顯得高大上一些,但是由于容錯率相對比較低(就是不容易讀出來),所以市面上還是比較少的.

  NSArray *filterArr = [CIFilter filterNamesInCategories:@[kCICategoryBuiltIn]];   //對
    
    NSLog(@"%@",filterArr); //所有內建過濾器,找CR... 二維碼的
    
    //創建二維碼過濾器
    CIFilter * qrfilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    
    //設置默認屬性(老油條)
    [qrfilter setDefaults];
    
    //我們需要給 二維碼過期器 設置一下屬性,給它一些東西,讓它去生成圖片吧,那些屬性呢,跳進去看
    NSLog(@"%@",qrfilter.inputKeys);
    /*
     inputMessage,            //二維碼的信息
     inputCorrectionLevel     //二維碼的容錯率 ()到達一定值后,就不能識別二維碼了
     */
    
    //我們需要給 二維碼 的 inputMessage 設置值,  這是私有屬性,我們 使用KVC.給其私有屬性賦值
    
    //將字符串轉為NSData,去獲取圖片
    NSData * qrimgardata = [@"http://www.baidu.com" dataUsingEncoding:NSUTF8StringEncoding];
    
    //去獲取對應的圖片(因為測試,直接用字符串會崩潰)
    [qrfilter setValue:qrimgardata forKey:@"inputMessage"];
    
    //去獲得對應圖片 outPut
    CIImage *qrImage = qrfilter.outputImage;
    
    //圖片不清除,打印知道其 大小 為 (27,27). 進入 CIImage,看屬性,
    qrImage = [qrImage imageByApplyingTransform:CGAffineTransformMakeScale(9, 9)];
    
    
    //創建彩色過濾器   (彩色的用的不多)-----------------------------------------------------
    CIFilter * colorFilter = [CIFilter filterWithName:@"CIFalseColor"];
    
    //設置默認值
    [colorFilter setDefaults];
    
    //同樣打印這樣的 輸入屬性  inputKeys
    NSLog(@"%@",colorFilter.inputKeys);
    /*
     inputImage,   //輸入的圖片
     inputColor0,  //前景色
     inputColor1   //背景色
     */
    
    //KVC 給私有屬性賦值
    [colorFilter setValue:qrImage forKey:@"inputImage"];
    
    //需要使用 CIColor
    [colorFilter setValue:[CIColor colorWithRed:1 green:0 blue:0.8] forKey:@"inputColor0"];
    [colorFilter setValue:[CIColor colorWithRed:0 green:1 blue:0.4] forKey:@"inputColor1"];
    
    //設置輸出
    CIImage *colorImage = [colorFilter outputImage];
    
    
    _imageView.image = [UIImage imageWithCIImage:colorImage];

效果圖

屏幕快照 2017-02-10 下午3.34.16.png

4、中間加logo二維碼

  //
    NSArray *filters = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
    NSLog(@"%@",filters);
    
    //二維碼過濾器
    CIFilter *qrImageFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    
    //設置過濾器默認屬性 (老油條)
    [qrImageFilter setDefaults];
    
    //將字符串轉換成 NSdata (雖然二維碼本質上是 字符串,但是這里需要轉換,不轉換就崩潰)
    NSData *qrImageData = [@"你好,我愛你" dataUsingEncoding:NSUTF8StringEncoding];
    
    //我們可以打印,看過濾器的 輸入屬性.這樣我們才知道給誰賦值
    NSLog(@"%@",qrImageFilter.inputKeys);
    /*
     inputMessage,        //二維碼輸入信息
     inputCorrectionLevel //二維碼錯誤的等級,就是容錯率
     */
    
    
    //設置過濾器的 輸入值  ,KVC賦值
    [qrImageFilter setValue:qrImageData forKey:@"inputMessage"];
    
    //取出圖片
    CIImage *qrImage = [qrImageFilter outputImage];
    
    //但是圖片 發現有的小 (27,27),我們需要放大..我們進去CIImage 內部看屬性
    qrImage = [qrImage imageByApplyingTransform:CGAffineTransformMakeScale(20, 20)];
    
    //轉成 UI的 類型
    UIImage *qrUIImage = [UIImage imageWithCIImage:qrImage];
    
    
    //----------------給 二維碼 中間增加一個 自定義圖片----------------
    //開啟繪圖,獲取圖形上下文  (上下文的大小,就是二維碼的大小)
    UIGraphicsBeginImageContext(qrUIImage.size);
    
    //把二維碼圖片畫上去. (這里是以,圖形上下文,左上角為 (0,0)點)
    [qrUIImage drawInRect:CGRectMake(0, 0, qrUIImage.size.width, qrUIImage.size.height)];
    
    
    //再把小圖片畫上去
    UIImage *sImage = [UIImage imageNamed:@"龍之母.jpg"];
    
    CGFloat sImageW = 100;
    CGFloat sImageH= sImageW;
    CGFloat sImageX = (qrUIImage.size.width - sImageW) * 0.5;
    CGFloat sImgaeY = (qrUIImage.size.height - sImageH) * 0.5;
    
    [sImage drawInRect:CGRectMake(sImageX, sImgaeY, sImageW, sImageH)];
    
    //獲取當前畫得的這張圖片
    UIImage *finalyImage = UIGraphicsGetImageFromCurrentImageContext();
    
    //關閉圖形上下文
    UIGraphicsEndImageContext();
    
    
    
    //設置圖片
    self.logoImageView.image = finalyImage;

效果圖

屏幕快照 2017-02-10 下午3.58.56.png

二維碼掃描

1.原生掃描用到的幾個類

@property (strong,nonatomic)AVCaptureDevice * device;
@property (strong,nonatomic)AVCaptureDeviceInput * input;
@property (strong,nonatomic)AVCaptureMetadataOutput * output;
@property (strong,nonatomic)AVCaptureSession * session;
@property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;

2.在viewDidLoad里創建它們

// Device
_device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

// Input
_input = [AVCaptureDeviceInputdeviceInputWithDevice:self.deviceerror:nil];

// Output
_output = [[AVCaptureMetadataOutputalloc]init];
[_outputsetMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];

// Session
_session = [[AVCaptureSessionalloc]init];
[_sessionsetSessionPreset:AVCaptureSessionPresetHigh];

3、連接輸入和輸出

if ([_sessioncanAddInput:self.input])
{
    [_sessionaddInput:self.input];
}

if ([_sessioncanAddOutput:self.output])
{
    [_sessionaddOutput:self.output];
}

4、設置條碼類型

_output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];

5、添加掃描畫面

_preview =[AVCaptureVideoPreviewLayerlayerWithSession:_session];
_preview.videoGravity =AVLayerVideoGravityResizeAspectFill;
_preview.frame =self.view.layer.bounds;
[self.view.layerinsertSublayer:_previewatIndex:0];

6、開始掃描

[_sessionstartRunning];

7、最后實現協議AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
   NSString *stringValue;
   if ([metadataObjectscount] >0){
   //停止掃描
   [_sessionstopRunning];        
   AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjectsobjectAtIndex:0];
   stringValue = metadataObject.stringValue;        
  }
}

這里就是可以成功掃描二維碼了,但是這是個全屏,不太好看,需要我們設置一下掃描范圍

關鍵代碼
// 設置掃描范圍(每一個取值0~1,以屏幕右上角為坐標原點)
    // 注:微信二維碼的掃描范圍是整個屏幕,這里并沒有做處理(可不用設置)
    output.rectOfInterest = CGRectMake(0.05, 0.2, 0.7, 0.6);

參考:http://www.cocoachina.com/ios/20161009/17696.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,523評論 25 708
  • 不得不說,二維碼是小日本的一個偉大發明,它密度小、信息容量大、容錯能力強、成本低、制作難度低等優點,使得二維碼得到...
    杰森_Jason閱讀 5,730評論 8 10
  • 自從昨日給無戒老師做了個二維碼設計后,很多簡友都紛紛來問二維碼是如何設計才會好看呢? 由于此次教程復雜各位,請把設...
    夏唸薇閱讀 4,828評論 13 21
  • 從來就不喜歡《白蛇傳》的故事。原因很簡單,因為始終覺得,許仙太沒有可愛之處。 好像故事從一開始,就是白娘子在主動。...
    涓子Fiona閱讀 809評論 1 51
  • 這個世界是如此喧囂 而我的內心是安靜的 我從古老的橋上走過 佛面初秋繁美的群星 簇擁的是永恒的秋月 剎時銀河贈我的...
    ad2a2c36a2d3閱讀 275評論 0 1