鉴于之前做项目二维码的生成,解析用的都是zxing,zbar这些第三方的东西,用起来也很方便;最近闲来无事,了解了下ios sdk对于二维码的支持,上一篇文章介绍的是关于二维码的扫描:http://my.oschina.net/u/1432769/blog/542799; 这篇介绍下CIFilter、CIDetector实现二维码的过程需要注意的一些问题
一、生成
二维码的生成可以使用coreimage.framework这个里面的CIFilter类来生成
+ (CIImage *)ciImageFromString:(NSString *)qrString {
NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];
return qrFilter.outputImage;
}
+ (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat) size {
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
// 创建bitmap;
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);
// 保存bitmap到图片
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return [UIImage imageWithCGImage:scaledImage];
}
生成没有碰到什么问题,直接调用上面的就可以生成简单的二维码,(其他的包括颜色,或者加上logo,不在这列)
二、解析
在解析指定image的时候,可以用 CIDetector(这个类还可以进行人脸识别等功能)来进行,主要解析的过程,代码比较简单,如下
+ (NSString *)stringFromCiImage:(CIImage *)ciimage {
NSString *content = @"" ;
if (!ciimage) {
return content;
}
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode
context:[CIContext contextWithOptions:nil]
options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
NSArray *features = [detector featuresInImage:ciimage];
if (features.count) {
for (CIFeature *feature in features) {
if ([feature isKindOfClass:[CIQRCodeFeature class]]) {
content = ((CIQRCodeFeature *)feature).messageString;
break;
}
}
} else {
NSLog(@"未正常解析二维码图片, 请确保iphone5/5c以上的设备");
}
return content;
}
但是,由于本人用的是5c进行调试:
1、发现每次获取的features都是nil, 无法正常解析,通过上网查阅资料发现,有说让换图片,有让用真机的,很多种说法;但是各种尝试各种失败告终,最后在stackoverflow看到关于5s及CIDetectorTypeQRCode的问题,得到提示,然后果断换了mini4进行调试,发现可以正常解析,接着拿了mini2调试,发现依旧可以,只有手上的5c是没法正常解析
2、通过“1”中的调试,猜测可能CIDetector的二维码解析需要是5、5c以后的设备,继续上网查阅,发现一个文章里面,作者提到Ta的解释,用真机或者5s以上的模拟器可以正常解析,那么通过本人根据提示使用模拟器调试,发现确实需要是5s及以上模拟器才能正常解析