iOS中的二维码

前言

在iOS中,经常可以看到,有很多商业都需要APP,例如像BOSS直聘,微信都要用到扫描二维码.而且前几天面试的时候面试官问了这个为.结果自己也不会.虽然能在github下载例子拖进项目.但是

如果你不能将知识通过简洁的语言表达出来,那说明你还没掌握这个知识.

二维码

二维码是矩阵条形码类型中的一种商标类型.一个条形码能够储存字母,数字,二进制,和汉字四种标准数据类型.扫描设备通过二维码角落的三个正方形定位.在通过正方形里面的小正方形计算图片的大小,方向.中间的小黑点则包括二进制数字,其中有一部分数据用于纠错算法.
纠错等级越高,储存的容量越少.总共有四个等级.

等级 容量
Level L (Low) 7% of codewords can be restored
Level M (Medium) 15% of codewords can be restored
Level Q (Quartile) 25% of codewords can be restored
Level H (High) 30% of codewords can be restored

实现

AVFoundation是唯一一个你可以用来播放或者创造基于时间的影声媒介的框架.而二维码属于这个框架之中的一个小小模块.所以得按照AVFoundation流程创建一个扫描回话.如果仅仅需要简单得扫码功能而不需要详细地控制.可以直接在viewDidLoad中添加以下代码:

// 创建一个会话
self.session = [[AVCaptureSession alloc] init];
// 创建一个默认的后摄像头视频设备
self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// 从一个设备中创建一个设备输入源,可以用来获取摄像头捕捉到的数据
self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device
                                              error:nil];
// 为回话添加一个输入源
[self.session addInput:self.input];
// 创建一个能扫描输出源,可以扫描二维码,条形码,等
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[self.session addOutput:output];
self.output = output;
// 设置代理,当扫描取得数据时,会再阻塞主线程.
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// 设备数据类型,当前只能扫描二维码
output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];
// 创建一个视频预览图层
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
previewLayer.frame = self.view.bounds;
// 缩放方式
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:previewLayer];
[self.session startRunning];

然后继承代理AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
  AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0];
  NSLog(@"QR_code is %@",metadataObject.stringValue);
}

细节控制

上面的代码能够应用那些简单得需求了.当前,还有很多细节并没有控制.

  • 卡顿 由于[self.session startRunning]可能会花费比较长的时间.可能会发费0.5s,会有一个卡顿的现象.session的初始化和配置都放在异步线程中.但是有关previewLayer的操作要放在主线程中更新.并在加载时显示UIActivityIndicatorView动画.

  • 权限viewDidLoadviewDidAppear中添加权限的检测和权限的获取.在获取权限和viewDidDisappear之前,必须将当前的session暂停.

  • 扫描区域 上面的整个代码中,默认扫描整一个layer.像微信这些app都只扫描中间的部分区域.AVCaptureVideoPreviewLayer中有属性rectOfInterest,控制我们所扫描的区域.默认值为(0.0, 0.0, 1.0, 1.0).不过AVCaptureVideoPreviewLayer有一个简便的方法计算这个百分比metadataOutputRectOfInterestForRect:,通过坐标计算比例,利用这个方法可以快速计算百分比.

  • 识别图片中的二维码 利用CIDetector设别图片中的二维码.

    -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
    {
      UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
      if (image) {
        CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
    
        NSData *data = UIImagePNGRepresentation(image);
        CIImage *img = [CIImage imageWithData:data];
        NSArray *features = [detector featuresInImage:img options:nil];
        if (features.count > 0) {
          for (CIFeature *feature in features) {
          if (![feature  isKindOfClass:[CIQRCodeFeature class]]) continue;
            NSLog(@"msg:%@", [(CIQRCodeFeature *)feature messageString]);
          }
          } else {
            NSLog(@"No feature!!!");
          }
          } else {
            NSLog(@"No image!!!");
          }
    
          [picker dismissViewControllerAnimated:YES completion:NULL];
        }
    

我自己模仿微信的扫描界面,自己写了一个二维码界面并实现了以上的控制,直接考进项目就可以使用.
AKQRCodeScan

生成二维码

在网上找了一个博客 使用CIFilter生成二维码并自定义

总结

引用文章

二维码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 一、二维码简介 从iOS7开始集成了二维码的生成和读取功能此前被广泛使用的zbarsdk目前不支持64位处理器 二...
    阿凡提说AI阅读 518评论 0 0
  • 本文中使用的是系统原生coreimage,实现功能​二维码扫描和解析和生成 ===================...
    child_cool阅读 431评论 0 0
  • 总是忍不住手贱去看 去期待 然后就是伤心 有时候是一上午 有时候是就好 每次都自己舔伤口 还假装从未受伤 都说早上...
    诗子w阅读 116评论 0 0
  • 在你没爱上自己之前,你不会爱上任何人。 等你爱上自己,你就会爱上你的父母,爱上你的爱人爱孩子,因为我们本为一体,我...
    润悦阅读 113评论 0 0