转载

二维码扫描和创建(上)

扫描二维码(包括读取和解码)

扫描二维码 OC 的开源库有 ZBar和ZXingiOS7 以后iOS拥有原生的扫码功能。

我在iPhone项目 扫码神奇 中使用的就是下面第三种方法,大家可以到APPStore搜索 扫码神奇 ,下载体验一下(记得给个好评呦)。 扫码神奇 下载链接: https://itunes.apple.com/cn/app/id1074173840

二维码扫描和创建(上)

好了下面是具体实现介绍:

ZXing

现在 OC 版本已经停止维护,Java版本还在维护, github 链接: https://github.com/zxing/zxing ,现在也很少有人使用,在 唐巧 的一篇12年 http://blog.devtang.com/blog/2012/12/23/use-zxing-library/ 文章中有关于 ZXing的 配置过程,不过好像他好久没有更新了。 ZXing 相对于 ZBar 的好处是读取和扫码速度快,但是整合到 Xcode 项目中比较痛苦。

ZBar

ZBargithub 地址: https://github.com/bmorton/ZBarSDK ,在github上下载的 .a 文件不支持 64位 ,好像也有好今年没有更新了,不过我在网上找到了支持64位的 .a 文件,下载链接: https://markobl.com/2015/03/27/zbar-sdk-64-bit-for-iphone-6-and-ios-8-download/ ,下面说一下 ZBar 的集成步骤:

  • 从 github 上下载源文件,解压后如下图,把Headers文件夹拖入到项目中。

  • 从 64位.a文件 下载支持64位的.a文件,添加到项目中

  • 在新工程中导入以下框架: AVFoundation.framework、CoreMedia.framework、CoreVideo.framework、QuartzCore.framework、libiconv.dylib

  • 在需要使用的页面 .h 文件中引用头文件 #import "ZBarSDK.h"

.m 文件中在点击开始扫描的按钮中实现:

ZBarReaderViewController *reader = [ZBarReaderViewController new];     reader.readerDelegate = self;   reader.supportedOrientationsMask = ZBarOrientationMaskAll;      ZBarImageScanner *scanner = reader.scanner;     [scanner setSymbology: ZBAR_I25                    config: ZBAR_CFG_ENABLE                        to: 0];     [self presentViewController:reader                        animated:YES                      completion:^{     }]; 

还要实现 代理

- (void) imagePickerController: (UIImagePickerController*) reader didFinishPickingMediaWithInfo: (NSDictionary*) info{     id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];       ZBarSymbol *symbol = nil;       for(symbol in results)            break;           [self dismissViewControllerAnimated:YES                              completion:^{                              }];       NSString *code = [NSString stringWithString:symbol.data];    } 

ZBar 有一个弊端,因为他是静态文件,所以自定义相机比较困难,只能进行简单的修改,我尝试实现微信扫码效果没有实现。

iOS原生扫码

iOS7以后APPle有了自己原生的扫码接口,我当然要义无反顾地选择使用原生的了,下面是我在项目中的部分代码: 在.m文件中:

#import <AVFoundation/AVFoundation.h> @interface SysScannerController ()<AVCaptureMetadataOutputObjectsDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate> @property (nonatomic, strong) AVCaptureSession *session;//输入输出的中间桥梁 @property (strong,nonatomic)AVCaptureDevice *device; @property (strong,nonatomic)AVCaptureDeviceInput *input; @property (strong,nonatomic)AVCaptureMetadataOutput *output; @property (strong,nonatomic)AVCaptureVideoPreviewLayer *preview; @end 

懒加载:

#pragma mark - Setter & Getter -(UIView *)line{     if (_line == nil) {         _line = [[UIView alloc] initWithFrame:CGRectMake((ScreenFrameWith-180)/2, ScreenFrameHeight/3.f, 180, 4)];         _line.backgroundColor=[UIColor whiteColor];         [self.view addSubview:_line];     }     return _line; }  -(AVCaptureDevice *)device{     if (_device == nil) {         _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];     }     return _device; } -(AVCaptureDeviceInput *)input{     if (_input == nil) {         _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];     }     return _input; } -(AVCaptureMetadataOutput *)output{     if (_output == nil) {         _output = [[AVCaptureMetadataOutput alloc]init];         [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];         //限制扫描区域(上左下右)         [ _output setRectOfInterest : CGRectMake (1/6.f,1/6.f,4/6.f,4/6.f)];     }     return _output; }  - (AVCaptureSession *)session{     if (_session == nil) {         // Session         _session = [[AVCaptureSession alloc]init];         [_session setSessionPreset:AVCaptureSessionPresetHigh];         if ([_session canAddInput:self.input])         {             [_session addInput:self.input];         }          if ([_session canAddOutput:self.output])         {             [_session addOutput:self.output];         }     }     return _session; }  -(AVCaptureVideoPreviewLayer *)preview{     if (_preview == nil) {         _preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];      }     return _preview; } 

-viewDidLoad 中调用下面函数:

- (void)setupCamera {     //1.     if(self.device == nil){         [self showAlertTipWithTitle:@"未检测到相机" andMessage:@"请检查相机设备是否正常"];         return ;     }     // 2.添加预览图层     [self.view.layer insertSublayer:self.preview atIndex:0];     self.preview.frame = self.view.bounds;     // 3.设置输出能够解析的数据类型     // 注意点: 设置数据类型一定要在输出对象添加到会话之后才能设置     self.output.metadataObjectTypes = self.output.availableMetadataObjectTypes;     // 4.设置监听监听输出解析到的数据     [self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];     // 5.开始扫描     [self.session startRunning];  } 

实现 AVCaptureMetadataOutputObjectsDelegate 代理:

#pragma mark AVCaptureMetadataOutputObjectsDelegate  - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {      if ([metadataObjects count] >0)     {         AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];          if ([metadataObject isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {             NSString *stringValue = [metadataObject stringValue];             if (stringValue != nil) {                 [self.session stopRunning];                 //扫描结果                 self.scannedResult=stringValue;             }          }     } } 

iOS原生的扫码界面你可以随意的自定义了,和自定义相机一样,这里就不做介绍了。

扫描相册中的二维码

扫描相册中的二维码,首先打开相册然后先在UIImagePickerControllerDelegate代理方法中:

 #pragma mark - imagePickerController delegate - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {     //1.获取选择的图片     UIImage *image = info[UIImagePickerControllerOriginalImage];     //2.初始化一个监测器     CIDetector*detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{ CIDetectorAccuracy : CIDetectorAccuracyHigh }];      [picker dismissViewControllerAnimated:YES completion:^{         //监测到的结果数组         NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];         if (features.count >=1) {             /**结果对象 */             CIQRCodeFeature *feature = [features objectAtIndex:0];             NSString *scannedResult = feature.messageString;             self.scannedResult=scannedResult;             [self performSegueWithIdentifier:@"ToResult" sender:self];         }         else{             [self showAlertTipWithTitle:@"提示" andMessage:@"该图片没有包含一个二维码!"];         }     }]; } 

好了,关于扫描二维码今天就说到这,下一篇我会分享创建二维码功能。 扫描二维码和创建二维码项目展示:APPStore搜索 扫码神奇 。上一篇文章 http://www.lvesli.com/?p=412 中有扫码神奇的具体介绍:

关注微信公众号: lecoding 实时关注文章更新。你也可以扫描下方二维码关注我们:

二维码扫描和创建(上)

原文  http://www.lvesli.com/?p=421
正文到此结束
Loading...