二维码的生成与识别

来源:互联网 发布:淘宝正规刷信誉平台 编辑:程序博客网 时间:2024/06/13 03:33

二维码的生成与识别

刚刚写了一篇扫描二维码的文章,就想着怎么样才能实现像微信那样的识别图片中的二维码呢?百度一下,发现基本上都是利用ZXing或ZBar来实现的,难道系统就没有方法吗?于是再继续找,终于发现了使用CoreImage类来实现二维码的识别。

  • 二维码的生成与识别
    • CoreImage简介
    • 生成二维码
      • 生成滤镜
      • 查询滤镜信息
      • 获取二维码图像
    • 识图二维码
    • 效果演示

CoreImage简介

iOS提供的CoreImage框架非常强大,简直可以用来完全实现自己的”PhotoShop”,当然我本人是只会点皮毛。现在就利用CoreImage中的CIFilter和CIDetector来实现二维码的生成和识别。

生成二维码

生成滤镜

生成二维码,主要是使用CIFilter类,该类代表了各种滤镜,利用该类的方法,可生成对应的滤镜:

+ (nullable CIFilter *) filterWithName:(NSString *) name;

查询滤镜信息

那怎么知道有哪些滤镜可以使用呢?该类还提供了另外一个方法,供我们查询可以使用哪些滤镜:

+ (CI_ARRAY(NSString*) *)filterNamesInCategory:(nullable NSString *)category;

该方法会返回一个包含指定分类的可用滤镜集合,那么问题又来了,我们又如何知道有哪些分类呢?滤镜名称只是一个字符串,在头文件中并没有任何相关的属性定义,但是分类是有的,对应请查看CIFilter.h

/* Categories */CORE_IMAGE_EXPORT NSString * const kCICategoryDistortionEffect;CORE_IMAGE_EXPORT NSString * const kCICategoryGeometryAdjustment;CORE_IMAGE_EXPORT NSString * const kCICategoryCompositeOperation;CORE_IMAGE_EXPORT NSString * const kCICategoryHalftoneEffect;CORE_IMAGE_EXPORT NSString * const kCICategoryColorAdjustment;CORE_IMAGE_EXPORT NSString * const kCICategoryColorEffect;CORE_IMAGE_EXPORT NSString * const kCICategoryTransition;CORE_IMAGE_EXPORT NSString * const kCICategoryTileEffect;CORE_IMAGE_EXPORT NSString * const kCICategoryGenerator;CORE_IMAGE_EXPORT NSString * const kCICategoryReduction NS_AVAILABLE(10_5, 5_0);CORE_IMAGE_EXPORT NSString * const kCICategoryGradient;CORE_IMAGE_EXPORT NSString * const kCICategoryStylize;CORE_IMAGE_EXPORT NSString * const kCICategorySharpen;CORE_IMAGE_EXPORT NSString * const kCICategoryBlur;CORE_IMAGE_EXPORT NSString * const kCICategoryVideo;CORE_IMAGE_EXPORT NSString * const kCICategoryStillImage;CORE_IMAGE_EXPORT NSString * const kCICategoryInterlaced;CORE_IMAGE_EXPORT NSString * const kCICategoryNonSquarePixels;CORE_IMAGE_EXPORT NSString * const kCICategoryHighDynamicRange;CORE_IMAGE_EXPORT NSString * const kCICategoryBuiltIn;CORE_IMAGE_EXPORT NSString * const kCICategoryFilterGenerator NS_AVAILABLE(10_5, 9_0);

我们要生成二维码,可以使用kCICategoryGenerator,查看到该分类下面有一个CIQRCodeGenerator,别看这家伙的名字长的像一个类,其实就是一个字符串,所以在传入的时候只需以字符串的形式传入就行了。 个人感觉苹果这种做法有点操蛋,简单的找一个滤镜的名字,都这么麻烦。代码如下所示:

_QRCodeFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];

如果说这就觉得操蛋了,那接下来还有更加麻烦的事。要想使用CIFilter生成二维码,需要设置一些属性值,方法是通过KVC,setValue:forKey,我们需要设置两个属性,那么同名字一样,我哪知道要设置哪些属性?其实方法都是一样的,CIFilter还提供了inputKeys,outputKeys,attributes属性供我们查询,我们可以将attributes的内容输出来,如下所示:

{    "CIAttributeFilterAvailable_Mac" = "10.9";    "CIAttributeFilterAvailable_iOS" = 7;    CIAttributeFilterCategories =     (        CICategoryGenerator,        CICategoryStillImage,        CICategoryBuiltIn    );    CIAttributeFilterDisplayName = "QRCode Generator";    CIAttributeFilterName = CIQRCodeGenerator;    CIAttributeReferenceDocumentation = "http://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CIQRCodeGenerator";    inputCorrectionLevel =     {        CIAttributeClass = NSString;        CIAttributeDefault = M;        CIAttributeDescription = "QRCode correction level L, M, Q, or H.";        CIAttributeDisplayName = CorrectionLevel;    };    inputMessage =     {        CIAttributeClass = NSData;        CIAttributeDisplayName = Message;    };}

在这些属性里面,我们可以看到,上面一些都是苹果设置的属性,我们需要设置的就是最后两个属性inputCorrectionLevel和inputMessage,
inputCorrectionLevel:该参数应该是代表生成二维码的精度(自己猜的)
inputMessage:该参数代表要生成的二维码中所包含的信息
从CIAttributeClass字段中,我们可以见到,inputCorrectionLevel的值是NSString类型,并且根据CIAttributeDescription知道可选的值有L,M,Q,H等。
而inputMessage的类型则是NSData。

获取二维码图像

设置这两个属性之后,我们就可以通过以下属性来获取处理后的图片:

@property (readonly, nonatomic, nullable) CIImage *outputImage NS_AVAILABLE(10_10, 5_0);

该方法返回一个CIImage,可以转换成UIImage并设置在UIImageView上。代码如下所示:

[_QRCodeFilter setValue:@"H" forKey:@"inputCorrectionLevel"];    [_QRCodeFilter setValue:[_messageTextField.text dataUsingEncoding:NSUTF8StringEncoding] forKey:@"inputMessage"];    [_QRCodeImageView setImage:[UIImage imageWithCIImage:_QRCodeFilter.outputImage]];

至此,就能成功生成一个二维码。接下来就是利用CIDetector来识别二维码。

识图二维码

相对起使用CIFilter生成二维码来说,识别二维码可要简单太多了,我们只需要实例化CIDetector类,并采用以下方法,便可以获取:

- (CI_ARRAY(CIFeature*) *)featuresInImage:(CIImage *)image    NS_AVAILABLE(10_7, 5_0);

该方法返回包含CIFeature类的数组,对于二维码来说,该数组中的类型应该是CIQRCodeFeature类的实例,我们只需要通过其中的messageString属性即可以获取到二维码中的内容。

-(void)longPressed:(UILongPressGestureRecognizer*)recognizer {    CIImage* image = _QRCodeFilter.outputImage;    NSArray* array =[_QRCodeDector featuresInImage:image];    for (CIFeature* feature in array) {        if([feature isKindOfClass:[CIQRCodeFeature class]]) {            CIQRCodeFeature* QRCodeFeature = (CIQRCodeFeature*)feature;            [[[UIAlertView alloc] initWithTitle:@"二维码" message:QRCodeFeature.messageString delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil] show];            return;        }    }    return ;}

效果演示

最终的效果演示如下图所示:
效果演示

0 0
原创粉丝点击