代码地址如下:
http://www.demodashi.com/demo/12551.html

一、效果预览:



功能描述:WSLNativeScanTool是在利用原生API的条件下封装的二维码扫描工具,支持二维码的扫描、识别图中二维码、生成自定义颜色和中心图标的二维码、监测环境亮度、打开闪光灯这些功能;WSLScanView是参照微信封装的一个扫一扫界面,支持线条颜色、大小、动画图片、矩形扫描框样式的自定义;这个示例本身就是仿照微信的扫一扫功能实现的。

二、实现

主要代码如下:

  • 初始化扫描识别对象
- (AVCaptureSession *)session{

    if (_session == nil){
//获取摄像设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if (!input){
return nil;
} //创建二维码扫描输出流
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
//设置代理 在主线程里刷新
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//设置采集扫描区域的比例 默认全屏是(0,0,1,1)
//rectOfInterest 填写的是一个比例,输出流视图preview.frame为 x , y, w, h, 要设置的矩形快的scanFrame 为 x1, y1, w1, h1. 那么rectOfInterest 应该设置为 CGRectMake(y1/y, x1/x, h1/h, w1/w)。
CGFloat x = CGRectGetMinX(self.scanFrame)/ CGRectGetWidth(self.preview.frame);
CGFloat y = CGRectGetMinY(self.scanFrame)/ CGRectGetHeight(self.preview.frame);
CGFloat width = CGRectGetWidth(self.scanFrame)/ CGRectGetWidth(self.preview.frame);
CGFloat height = CGRectGetHeight(self.scanFrame)/ CGRectGetHeight(self.preview.frame);
output.rectOfInterest = CGRectMake(y, x, height, width); // 创建环境光感输出流
AVCaptureVideoDataOutput *lightOutput = [[AVCaptureVideoDataOutput alloc] init];
[lightOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; _session = [[AVCaptureSession alloc] init];
//高质量采集率
[_session setSessionPreset:AVCaptureSessionPresetHigh];
[_session addInput:input];
[_session addOutput:output];
[_session addOutput:lightOutput]; //设置扫码支持的编码格式(这里设置条形码和二维码兼容)
output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeCode128Code];
} return _session;
}
  • 扫描出结果的代理方法
#pragma mark -- AVCaptureMetadataOutputObjectsDelegate
//扫描完成后执行
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ if (metadataObjects.count > 0){
AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects firstObject];
// 扫描完成后的字符
// NSLog(@"扫描出 %@",metadataObject.stringValue);
if(self.scanFinishedBlock != nil){
self.scanFinishedBlock(metadataObject.stringValue);
}
}
}
#pragma mark- AVCaptureVideoDataOutputSampleBufferDelegate的方法
//扫描过程中执行,主要用来判断环境的黑暗程度
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{ if (self.monitorLightBlock == nil) {
return;
} CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL,sampleBuffer, kCMAttachmentMode_ShouldPropagate);
NSDictionary *metadata = [[NSMutableDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
CFRelease(metadataDict);
NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
float brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue]; // NSLog(@"环境光感 : %f",brightnessValue); // 根据brightnessValue的值来判断是否需要打开和关闭闪光灯
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
BOOL result = [device hasTorch];// 判断设备是否有闪光灯
if ((brightnessValue < 0) && result) {
// 环境太暗,可以打开闪光灯了
}else if((brightnessValue > 0) && result){
// 环境亮度可以
}
if (self.monitorLightBlock != nil) {
self.monitorLightBlock(brightnessValue);
} }

三、用法

  • 实例化WSLNativeScanTool工具类和WSLScanView界面类;用法很简单,头文件里注释的也挺详细的。
//输出流视图
UIView *preview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 0)];
[self.view addSubview:preview];
__weak typeof(self) weakSelf = self;
//构建扫描样式视图
_scanView = [[WSLScanView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 0)];
_scanView.scanRetangleRect = CGRectMake(60, 120, (self.view.frame.size.width - 2 * 60), (self.view.frame.size.width - 2 * 60));
_scanView.colorAngle = [UIColor greenColor];
_scanView.photoframeAngleW = 20;
_scanView.photoframeAngleH = 20;
_scanView.photoframeLineW = 2;
_scanView.isNeedShowRetangle = YES;
_scanView.colorRetangleLine = [UIColor whiteColor];
_scanView.notRecoginitonArea = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
_scanView.animationImage = [UIImage imageNamed:@"scanLine"];
_scanView.myQRCodeBlock = ^{
[WSLNativeScanTool createQRCodeImageWithString:@"https://www.jianshu.com/u/e15d1f644bea" andSize:CGSizeMake(250, 250) andBackColor:[UIColor whiteColor] andFrontColor:[UIColor orangeColor] andCenterImage:[UIImage imageNamed:@"piao"]];
createQRCodeController.qrString = @"https://www.jianshu.com/u/e15d1f644bea";
};
_scanView.flashSwitchBlock = ^(BOOL open) {
[weakSelf.scanTool openFlashSwitch:open];
};
[self.view addSubview:_scanView];
//初始化扫描工具
_scanTool = [[WSLNativeScanTool alloc] initWithPreview:preview andScanFrame:_scanView.scanRetangleRect];
_scanTool.scanFinishedBlock = ^(NSString *scanString) {
NSLog(@"扫描结果 %@",scanString);
[weakSelf.scanTool sessionStopRunning];
[weakSelf.scanTool openFlashSwitch:NO];
};
_scanTool.monitorLightBlock = ^(float brightness) {
NSLog(@"环境光感 : %f",brightness);
if (brightness < 0) {
// 环境太暗,显示闪光灯开关按钮
[weakSelf.scanView showFlashSwitch:YES];
}else if(brightness > 0){
// 环境亮度可以,且闪光灯处于关闭状态时,隐藏闪光灯开关
if(!weakSelf.scanTool.flashOpen){
[weakSelf.scanView showFlashSwitch:NO];
}
}
};
[_scanTool sessionStartRunning];
[_scanView startScanAnimation];

四、项目结构

五、其他补充

暂没

iOS 原生二维码扫描和生成

代码地址如下:
http://www.demodashi.com/demo/12551.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

iOS 原生二维码扫描和生成的更多相关文章

  1. iOS 原生二维码扫描(可限制扫描区域)

    篇文章的主要原因不是展示如何使用  AVFoundation 来进行二维码扫描,更主要的是限制扫描二维码的范围.(因为默认的是全屏扫描) 项目遇到扫描二维码的功能需求,这里我放弃了使用三方库,而采用了 ...

  2. 【转】 iOS 原生二维码扫描(可限制扫描区域)

    在用 AVFoundation 完成扫码后,遇到2个问题: 1,如何限制扫描范围? 2.条形码如何扫描? 一位朋友的文章帮助了我,特地转来,可以帮到有需要的朋友. 原文:http://blog.csd ...

  3. iOS 原生二维码扫描,带扫描框和扫描过程动画

    在代码中使用了相对布局框架Masonry 准备两张图片,一张是扫描边框,一张是扫描时的细线分别命名 scanFrame.png和scanLine.png并提前放入工程 导入相对布局头文件 #defin ...

  4. iOS:原生二维码扫描

    做iOS的二维码扫描,有两个第三方库可以选择,ZBar和ZXing.今天要介绍的是iOS7.0后AVFoundation框架提供的原生二维码扫描. 首先需要添加AVFoundation.framewo ...

  5. iOS开发技术 - 二维码扫描、生成

    QRecLevel:QR_ECLEVEL_H // 二维码容错率,最高为30%(即QR_ECLEVEL_H),即LOGO有大                                       ...

  6. iOS开发-二维码扫描和应用跳转

    iOS开发-二维码扫描和应用跳转   序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如Z ...

  7. Android二维码扫描、生成

    Android二维码扫描.生成 现在使用二维码作为信息的载体已经越来越普及,那么二维码的生成以及扫描是如何实现的呢 google为我们提供了zxing开源库供我们使用 zxing GitHub源码地址 ...

  8. Firemonkey 原生二维码扫描优化

    之前用了ZXing的Delphi版本,运行自带的例子,速度非常慢,与安卓版本的相比查了很多,因此打算使用集成jar的方法,但是总觉得美中不足. 经过一番研究,基本上解决了问题. 主要有两方面的优化: ...

  9. Swift:使用系统AVFoundation实现二维码扫描和生成

    系统提供的AVCaptureSession仅仅适用于iOS7.0以上的系统.之前的请用Zbar来替代 下载地址:http://download.csdn.net/detail/huobanbengku ...

随机推荐

  1. 关于"implicit declaration of function 'gettimeofday' is invalid in c99"的解决

    http://blog.csdn.net/macmini/article/details/10503799 当我们使用 gettimeofday(&time, NULL);时,会出现这样一个W ...

  2. xen 不同后端存储方案的性能对比

    概述 在xen平台下,一般使用文件来模拟一个磁盘.在xen中使用文件来模拟磁盘有3种方式, blkback 直接操作 blktap2 直接将文件映射为一个裸块设备,这样vm可以直接用phy的方式进行文 ...

  3. 解析Linux内核的基本的模块管理与时间管理操作---超时处理【转】

    转自:http://www.jb51.net/article/79960.htm 这篇文章主要介绍了Linux内核的基本的模块管理与时间管理操作,包括模块加载卸载函数的使用和定时器的用法等知识,需要的 ...

  4. java基础练习 18

    import java.util.Scanner; public class Eightheen { /*判断一个素数能被几个9整除*/ public static void main(String[ ...

  5. Appium+python自动化7-输入中文【转载】

    前言 在做app自动化过程中会踩很多坑,咱们都是用的中文的app,所以首先要解决中文输入的问题! 本篇通过屏蔽软键盘,绕过手机的软键盘方法,解决中文输入问题. 一.定位搜索 1.打开淘宝点搜索按钮,进 ...

  6. js正则常用的一些东西

    mdn的正则文档 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions js正则表达式的分 ...

  7. sql:将秒转化成时分秒格式

    DECLARE @a int=20000 SELECT CONVERT(VARCHAR(10),@a/60)+'分'+CONVERT(VARCHAR(10),@a%60)+'秒' --333分20秒 ...

  8. Ubuntu下触控板手势调节软件xSwipe

    楼主进了一台Thinkpad T450s,触控板支持4点触控,安装了ubuntu14.04 LTS之后,触控板只剩下双指滑动了,略有不爽,各种google,百度. 真找到办法了. 首先得知了touch ...

  9. Xamarin XAML语言教程构建进度条ProgressBar

    Xamarin XAML语言教程构建进度条ProgressBar Xamarin XAML语言教程构建进度条ProgressBar,ProgressBar被称为进度条,它类似于没有滑块的滑块控件.进度 ...

  10. Jenkins部署+svn

    Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括: 1.持续的软件版本发布/测试项目. 2.监控外部调用执行的工作.       确保java工作环境jdk.tom ...