详细易懂的二维码的扫描、识别与生成
2016-11-10 16:29
615 查看
ios7之前我们实现二维码扫描是借助第三方(ZBar,ZXing等)来实现的,在ios7之后系统自己提供二维码扫描的方法,性能也要比第三方更好。
今天就来介绍一下原生二维码的使用,包括扫描二维码,从图片扫描二维码和生成二维码。讲解中只展示部分代码,具体请看Github Demo,里面的代码不多,也很容易看懂。
https://github.com/lisongrc/QRCodeDemo
扫描二维码
二维码扫描需要用到AVFoundation.framework,需要用先创建一个AVCaptureSession,然后设置输入输出流,以及扫描区域和支持的格式:
//获取摄像设备
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()];
//设置扫描区域的比例
CGFloat
width
= 300
/ CGRectGetHeight(self.view.frame);
CGFloat
height
= 300
/ CGRectGetWidth(self.view.frame);
output.rectOfInterest
= CGRectMake((1
- width)
/ 2,
(1-
height)
/ 2,
width,
height);
AVCaptureSession
*session
= [[AVCaptureSession
alloc]
init];
//高质量采集率
[session
setSessionPreset:AVCaptureSessionPresetHigh];
[session
addInput:input];
[session
addOutput:output];
//设置扫码支持的编码格式(这里设置条形码和二维码兼容)
output.metadataObjectTypes
= @[AVMetadataObjectTypeQRCode,
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeCode128Code];
然后用这个session生成一个AVCaptureVideoPreviewLayer加到某个view的layer上,就可以实时显示摄像头捕捉的内容了:
AVCaptureVideoPreviewLayer
*layer
= [AVCaptureVideoPreviewLayer
layerWithSession:self.session];
layer.videoGravity
= AVLayerVideoGravityResizeAspectFill;
layer.frame
= self.view.layer.bounds;
[self.view.layer
insertSublayer:layer
atIndex:0];
然后调用[self.session startRunning];开始捕获,当扫描出结果后会调用下面的代理方法,其中metadataObject.stringValue就是扫描后的结果。
#pragma
mark - AVCaptureMetadataOutputObjectsDelegate
-(void)captureOutput:(AVCaptureOutput
*)captureOutput
didOutputMetadataObjects:(NSArray
*)metadataObjects
fromConnection:(AVCaptureConnection
*)connection
{
if
(metadataObjects.count
> 0)
{
AVMetadataMachineReadableCodeObject
*metadataObject
= [metadataObjects
firstObject];
}
}
为了在黑夜也可以很好的扫描,可以设置一个闪光灯的开关:
#pragma
mark - 开关闪光灯
-
(void)rightBarButtonDidClick:(UIBarButtonItem
*)item
{
self.flashOpen
= !self.flashOpen;
AVCaptureDevice
*device
= [AVCaptureDevice
defaultDeviceWithMediaType:AVMediaTypeVideo];
if
([device
hasTorch]
&& [device
hasFlash])
{
[device
lockForConfiguration:nil];
if
(self.flashOpen)
{
device.torchMode
= AVCaptureTorchModeOn;
device.flashMode
= AVCaptureFlashModeOn;
}
else
{
device.torchMode
= AVCaptureTorchModeOff;
device.flashMode
= AVCaptureFlashModeOff;
}
[device
unlockForConfiguration];
}
}
扫描二维码
从图片扫描
有时候我们需要从图片中扫描二维码,或者从相册选择一张图片,代码如下,具体可以看demo。其中feature.messageString就是扫描后的结果。
-
(void)findQRCodeFromImage:(UIImage
*)image
{
CIDetector
*detector
= [CIDetector
detectorOfType:CIDetectorTypeQRCode
context:nil
options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
NSArray
*features
= [detector
featuresInImage:[CIImage
imageWithCGImage:image.CGImage]];
if
(features.count
>= 1)
{
CIQRCodeFeature
*feature
= [features
firstObject];
}
}
从图片扫描
生成二维码
生成二维码的代码很简单,代码如下。
/** 生成指定大小的黑白二维码 */
-
(UIImage
*)createQRImageWithString:(NSString
*)string
size:(CGSize)size
{
NSData
*stringData
= [string
dataUsingEncoding:NSUTF8StringEncoding];
CIFilter
*qrFilter
= [CIFilter
filterWithName:@"CIQRCodeGenerator"];
// NSLog(@"%@",qrFilter.inputKeys);
[qrFilter
setValue:stringData
forKey:@"inputMessage"];
[qrFilter
setValue:@"M"
forKey:@"inputCorrectionLevel"];
CIImage
*qrImage
= qrFilter.outputImage;
//放大并绘制二维码
(上面生成的二维码很小,需要放大)
CGImageRef
cgImage
= [[CIContext
contextWithOptions:nil]
createCGImage:qrImage
fromRect:qrImage.extent];
UIGraphicsBeginImageContext(size);
CGContextRef
context
= UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(context,
kCGInterpolationNone);
//翻转一下图片
不然生成的QRCode就是上下颠倒的
CGContextScaleCTM(context,
1.0,
-1.0);
CGContextDrawImage(context,
CGContextGetClipBoundingBox(context),
cgImage);
UIImage
*codeImage
= UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(cgImage);
return
codeImage;
}
黑白二维码
上面默认生成的时黑白二维码,不过我们也可以改颜色:
/** 为二维码改变颜色 */
-
(UIImage
*)changeColorForQRImage:(UIImage
*)image
backColor:(UIColor
*)backColor
frontColor:(UIColor
*)frontColor
{
CIFilter
*colorFilter
= [CIFilter
filterWithName:@"CIFalseColor"
keysAndValues:
@"inputImage",[CIImage
imageWithCGImage:image.CGImage],
@"inputColor0",[CIColor
colorWithCGColor:frontColor.CGColor],
@"inputColor1",[CIColor
colorWithCGColor:backColor.CGColor],
nil];
return
[UIImage
imageWithCIImage:colorFilter.outputImage];
}
为二维码改变颜色
有的二维码也会在中心加一个小图片,例如用户头像,代码如下:
/** 在二维码中心加一个小图 */
-
(UIImage
*)addSmallImageForQRImage:(UIImage
*)qrImage
{
UIGraphicsBeginImageContext(qrImage.size);
[qrImage
drawInRect:CGRectMake(0,
0,
qrImage.size.width,
qrImage.size.height)];
UIImage
*image
= [UIImage
imageNamed:@"small"];
CGFloat
imageW
= 50;
CGFloat
imageX
= (qrImage.size.width
- imageW)
* 0.5;
CGFloat
imgaeY
= (qrImage.size.height
- imageW)
* 0.5;
[image
drawInRect:CGRectMake(imageX,
imgaeY,
imageW,
imageW)];
UIImage
*result
= UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return
result;
}
中心加小图的二维码
其实也可以扫描条形码,大家可以对着条形码试一试,代码都是通用的。
今天就来介绍一下原生二维码的使用,包括扫描二维码,从图片扫描二维码和生成二维码。讲解中只展示部分代码,具体请看Github Demo,里面的代码不多,也很容易看懂。
https://github.com/lisongrc/QRCodeDemo
扫描二维码
二维码扫描需要用到AVFoundation.framework,需要用先创建一个AVCaptureSession,然后设置输入输出流,以及扫描区域和支持的格式:
//获取摄像设备
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()];
//设置扫描区域的比例
CGFloat
width
= 300
/ CGRectGetHeight(self.view.frame);
CGFloat
height
= 300
/ CGRectGetWidth(self.view.frame);
output.rectOfInterest
= CGRectMake((1
- width)
/ 2,
(1-
height)
/ 2,
width,
height);
AVCaptureSession
*session
= [[AVCaptureSession
alloc]
init];
//高质量采集率
[session
setSessionPreset:AVCaptureSessionPresetHigh];
[session
addInput:input];
[session
addOutput:output];
//设置扫码支持的编码格式(这里设置条形码和二维码兼容)
output.metadataObjectTypes
= @[AVMetadataObjectTypeQRCode,
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeCode128Code];
然后用这个session生成一个AVCaptureVideoPreviewLayer加到某个view的layer上,就可以实时显示摄像头捕捉的内容了:
AVCaptureVideoPreviewLayer
*layer
= [AVCaptureVideoPreviewLayer
layerWithSession:self.session];
layer.videoGravity
= AVLayerVideoGravityResizeAspectFill;
layer.frame
= self.view.layer.bounds;
[self.view.layer
insertSublayer:layer
atIndex:0];
然后调用[self.session startRunning];开始捕获,当扫描出结果后会调用下面的代理方法,其中metadataObject.stringValue就是扫描后的结果。
#pragma
mark - AVCaptureMetadataOutputObjectsDelegate
-(void)captureOutput:(AVCaptureOutput
*)captureOutput
didOutputMetadataObjects:(NSArray
*)metadataObjects
fromConnection:(AVCaptureConnection
*)connection
{
if
(metadataObjects.count
> 0)
{
AVMetadataMachineReadableCodeObject
*metadataObject
= [metadataObjects
firstObject];
}
}
为了在黑夜也可以很好的扫描,可以设置一个闪光灯的开关:
#pragma
mark - 开关闪光灯
-
(void)rightBarButtonDidClick:(UIBarButtonItem
*)item
{
self.flashOpen
= !self.flashOpen;
AVCaptureDevice
*device
= [AVCaptureDevice
defaultDeviceWithMediaType:AVMediaTypeVideo];
if
([device
hasTorch]
&& [device
hasFlash])
{
[device
lockForConfiguration:nil];
if
(self.flashOpen)
{
device.torchMode
= AVCaptureTorchModeOn;
device.flashMode
= AVCaptureFlashModeOn;
}
else
{
device.torchMode
= AVCaptureTorchModeOff;
device.flashMode
= AVCaptureFlashModeOff;
}
[device
unlockForConfiguration];
}
}
扫描二维码
从图片扫描
有时候我们需要从图片中扫描二维码,或者从相册选择一张图片,代码如下,具体可以看demo。其中feature.messageString就是扫描后的结果。
-
(void)findQRCodeFromImage:(UIImage
*)image
{
CIDetector
*detector
= [CIDetector
detectorOfType:CIDetectorTypeQRCode
context:nil
options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
NSArray
*features
= [detector
featuresInImage:[CIImage
imageWithCGImage:image.CGImage]];
if
(features.count
>= 1)
{
CIQRCodeFeature
*feature
= [features
firstObject];
}
}
从图片扫描
生成二维码
生成二维码的代码很简单,代码如下。
/** 生成指定大小的黑白二维码 */
-
(UIImage
*)createQRImageWithString:(NSString
*)string
size:(CGSize)size
{
NSData
*stringData
= [string
dataUsingEncoding:NSUTF8StringEncoding];
CIFilter
*qrFilter
= [CIFilter
filterWithName:@"CIQRCodeGenerator"];
// NSLog(@"%@",qrFilter.inputKeys);
[qrFilter
setValue:stringData
forKey:@"inputMessage"];
[qrFilter
setValue:@"M"
forKey:@"inputCorrectionLevel"];
CIImage
*qrImage
= qrFilter.outputImage;
//放大并绘制二维码
(上面生成的二维码很小,需要放大)
CGImageRef
cgImage
= [[CIContext
contextWithOptions:nil]
createCGImage:qrImage
fromRect:qrImage.extent];
UIGraphicsBeginImageContext(size);
CGContextRef
context
= UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(context,
kCGInterpolationNone);
//翻转一下图片
不然生成的QRCode就是上下颠倒的
CGContextScaleCTM(context,
1.0,
-1.0);
CGContextDrawImage(context,
CGContextGetClipBoundingBox(context),
cgImage);
UIImage
*codeImage
= UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(cgImage);
return
codeImage;
}
黑白二维码
上面默认生成的时黑白二维码,不过我们也可以改颜色:
/** 为二维码改变颜色 */
-
(UIImage
*)changeColorForQRImage:(UIImage
*)image
backColor:(UIColor
*)backColor
frontColor:(UIColor
*)frontColor
{
CIFilter
*colorFilter
= [CIFilter
filterWithName:@"CIFalseColor"
keysAndValues:
@"inputImage",[CIImage
imageWithCGImage:image.CGImage],
@"inputColor0",[CIColor
colorWithCGColor:frontColor.CGColor],
@"inputColor1",[CIColor
colorWithCGColor:backColor.CGColor],
nil];
return
[UIImage
imageWithCIImage:colorFilter.outputImage];
}
为二维码改变颜色
有的二维码也会在中心加一个小图片,例如用户头像,代码如下:
/** 在二维码中心加一个小图 */
-
(UIImage
*)addSmallImageForQRImage:(UIImage
*)qrImage
{
UIGraphicsBeginImageContext(qrImage.size);
[qrImage
drawInRect:CGRectMake(0,
0,
qrImage.size.width,
qrImage.size.height)];
UIImage
*image
= [UIImage
imageNamed:@"small"];
CGFloat
imageW
= 50;
CGFloat
imageX
= (qrImage.size.width
- imageW)
* 0.5;
CGFloat
imgaeY
= (qrImage.size.height
- imageW)
* 0.5;
[image
drawInRect:CGRectMake(imageX,
imgaeY,
imageW,
imageW)];
UIImage
*result
= UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return
result;
}
中心加小图的二维码
其实也可以扫描条形码,大家可以对着条形码试一试,代码都是通用的。
相关文章推荐
- 详细易懂的二维码的扫描、识别与生成
- 详细易懂的二维码的扫描、识别与生成
- 详细易懂的二维码的扫描、识别与生成②
- 二维码的生成和扫描识别
- 二维码的扫描、识别与生成
- Android平台二维码之生成,扫描 & 识别
- iOS之长按识别二维码/生成二维码/扫描二维码
- 扫描二维码、扫描条形码、相册获取图片后识别、生成带 Logo 二维码、支持微博微信 QQ 二维码扫描样式
- HTML5实现扫描识别二维码/生成二维码
- QRCode 扫描二维码、扫描条形码、相册获取图片后识别、生成带 Logo 二维码、支持微博微信 QQ 二维码扫描样式
- HTML5实现扫描识别二维码/生成二维码
- 二维码生成、扫描、图片识别(Zxing)
- iOS二维码生成、识别、扫描等
- Swift之二维码的生成、识别和扫描
- ionic AngularJS 生成二维码 扫描识别二维码
- 二维码的生成 识别 扫描 封装(Swift)
- Android平台生成二维码并实现扫描 & 识别功能
- android 二维码,条形码生成与扫描识别
- Android 二维码的扫描,识别与生成功能使用简介
- HTML5实现扫描识别二维码/生成二维码