凌雪
2018-11-09
来源 :网络
阅读 1278
评论 0
摘要:本文将带你了解IOS开发入门iOS二维码,希望本文对大家学IOS有所帮助。
本文将带你了解IOS开发入门iOS二维码,希望本文对大家学IOS有所帮助。
二维码
生成二维码
iOS7中,Apple引入了Core Image filter来生成二维码。使用CoreImage的CIQRCodeGenerator,仅用简单的几行代码就可以生成二维码。
CIQRCodeGenerator使用两个参数:
inputMessage表示字符串的data inputCorrectionLevel表示不同级别的容错率。从low (“L”, 7%), medium, (“M”, 15%), quartile (“Q”, 25%), 和 high (“H”, 30%)中选择。每个百分比表示弹性水平(resilience level),这决定了条形码对局部损伤的响应程度
所以创建二维码只需要几步
1.创建一个filter
2.设置其inputCorrectionLevel和inputMessage
3.获取结果图片
<code><code><code><code><code><code><code><code><code><code><code><code><code><code><code>CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; [qrFilter setValue:@"H" forKey:@"inputCorrectionLevel"];
NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding]; [qrFilter setValue:stringData forKey:@"inputMessage"];
CIImage *result = [qrFilter valueForKey:@"outputImage"];</code></code></code></code></code></code></code></code></code></code></code></code></code></code></code>
唯一的问题是,这里输出的图片非常的小。QR code生成器filter创建的图片是每个point对应一个方块。上面创建的图片是27X27个点
<code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><ciimage: 0="" 0x8f0b0a0="" 27="" extent=""></ciimage:></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code>
所以要把QR code绘制到一个比较大的上下文中,并把结果保存为UIImage。然而这里还有一个细节要注意,如果不禁用掉interpolation,得到的结果图片会非常的模糊
调整后生成二维码的代码如下:
<code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code>+ (UIImage *) resizeImageWithoutInterpolation:(UIImage *)sourceImage size:(CGSize)size
{
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextSetInterpolationQuality(UIGraphicsGetCurrentContext(), kCGInterpolationNone);
[sourceImage drawInRect:(CGRect){.size = size}];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
+ (UIImage *) imageWithCIImage: (CIImage *) aCIImage orientation: (UIImageOrientation) anOrientation
{
if (!aCIImage) return nil;
CGImageRef imageRef = [[CIContext contextWithOptions:nil] createCGImage:aCIImage fromRect:aCIImage.extent];
UIImage *image = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:anOrientation];
CFRelease(imageRef);
return image;
}
+ (UIImage *)QRImageWithString:(NSString *) string size:(CGSize)destSize;
{
//创建filter
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
if (!qrFilter)
{
NSLog(@"Error: Could not load filter");
return nil;
}
// 设置 correction level
// L 7% , M 15% , Q 25% , H 30%
[qrFilter setValue:@"H" forKey:@"inputCorrectionLevel"];
//设置输入的text
NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding];
[qrFilter setValue:stringData forKey:@"inputMessage"];
//获取输出的image
CIImage *outputImage = [qrFilter valueForKey:@"outputImage"];
UIImage *smallImage = [self imageWithCIImage:outputImage orientation: UIImageOrientationUp];
return [self resizeImageWithoutInterpolation:smallImage size:destSize];
}</code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code>
识别二维码
AV Foundation支持的机器可识别代码
一维码大量用于商店、生成制造业和零售业,可识别的一维码有:
UPCE EAN 8 EAN 13 Code 39 Code 39 Mod 43 Code 93 Code 128 Interleaved 2 of 5 (iOS 8 and later) ITF 14 (iOS 8 and later)
二维码:
PDF 417 QR Code Aztec Data Matrix (iOS 8 and later)
基本代码实现
代码与自定义相机的代码类似,需注意的点有:
1.捕捉的输出为AVCaptureMetadataOutput类型,通过设置其metadataObjectTypes属性,来指定感兴趣的扫描对象
<code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code> self.metadataOutput = [[AVCaptureMetadataOutput alloc] init];
if ([self.captureSession canAddOutput:self.metadataOutput]) {
[self.captureSession addOutput:self.metadataOutput];
dispatch_queue_t mainQueue = dispatch_get_main_queue();
[self.metadataOutput setMetadataObjectsDelegate:self queue:mainQueue];
NSArray *types = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];
self.metadataOutput.metadataObjectTypes = types;
}</code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code>
注意这里,设置了setMetadataObjectsDelegate的代理,需遵循AVCaptureMetadataOutputObjectsDelegate协议
2.实现AVCaptureMetadataOutputObjectsDelegate协议- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection 方法,如下:
<code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code>-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects != nil && [metadataObjects count] > 0) {
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
....
}
}
}</code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code>
可通过AVMetadataMachineReadableCodeObject类的stringValue属性获取二维码对应的字符串
其它属性
AVMetadataMachineReadableCodeObject类的其它属性
bounds提供了识别码的按坐标对齐的矩形边界 corners提供了角点字典表示的NSArray
利用这些属性可以绘制出识别码的大小
扫描框
扫码时 previewLayer 的扫描范围是整个可视范围的,但有些需求可能需要指定扫描的区域,虽然我觉得这样很没有必要,因为整个屏幕都可以扫又何必指定到某个框呢?但如果真的需要这么做可以设定 metadataOutput 的 rectOfInterest。
需要注意的是:
1.rectOfInterest 的值比较特别,需要进行转化。它的默认值是 (0.0, 0.0, 1.0, 1.0)。
<code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code>metadataOutput.rectOfInterest = [previewLayer metadataOutputRectOfInterestForRect:CGRectMake(80, 80, 160, 160)]; // 假设扫码框的 Rect 是 (80, 80, 160, 160) </code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code>
2.rectOfInterest 不可以直接在设置 metadataOutput 时接着设置,而需要在这个 AVCaptureInputPortFormatDescriptionDidChangeNotification 通知里设置,否则 metadataOutputRectOfInterestForRect: 转换方法会返回 (0, 0, 0, 0)。
<code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!
喜欢 | 0
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号