微信二维码图片长按 无法识别问题解析

前言

今天测试iOS APP过程中,发现生成图片分享到微信好友的时候,长按图片无法产生“识别图中二维码”的操作选项(新功能要求图片中带有APP二维码,用户看到后可以识别二维码下载),最终确认可能导致没有“识别图中二维码”的操作选项可能原因有两点:

  • 是在生成二维码的过程中在二维码中间添加了logo
  • 二维码生成精度问题


    微信二维码图片长按 无法识别问题解析_第1张图片
    331524453772_.pic_hd.jpg

生成二维码代码

第一步:iOS 原生方法生成二维码

+ (CIImage *)createQRForString:(NSString *)qrString {
    NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];
    CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    [qrFilter setValue:stringData forKey:@"inputMessage"];// Set the message content and error-correction level
    [qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];
    return qrFilter.outputImage;
}

第二步: iOS 生成高清二维码并添加logo

- (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat) size waterImageSize:(CGFloat)waterImagesize{
    CGRect extent = CGRectIntegral(image.extent);
    CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
    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];
    //创建CoreGraphics image
    CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
    CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
    CGContextScaleCTM(bitmapRef, scale, scale);
    CGContextDrawImage(bitmapRef, extent, bitmapImage);
    // 2.保存bitmap到图片
    CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
    CGContextRelease(bitmapRef); CGImageRelease(bitmapImage);
    UIImage *outputImage = [UIImage imageWithCGImage:scaledImage];
    UIGraphicsBeginImageContextWithOptions(outputImage.size, NO, [[UIScreen mainScreen] scale]);
    [outputImage drawInRect:CGRectMake(0,0 , size, size)];
    
    // 添加logo
    {
        UIImage *waterimage =  [MyAppSystemService iconImage];
        UIImage *circleImge  = [UIImage imageCircleTailorWithImage:waterimage];
        waterImagesize = waterImagesize * 0.8;  // 继续缩小logo 位置
        [circleImge drawInRect:CGRectMake((size-waterImagesize)/2.0, (size-waterImagesize)/2.0, waterImagesize, waterImagesize)];
    }
    
    UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
//    return newPic;
    return newPic;
}

问题分析

其中二维码精度设置的代码是

[qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];

这个是官方文档中对inputMessage和inputCorrectionLevel的解释

[CIQRCodeGenerator ](https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/#//apple_ref/doc/filter/ci/CIQRCodeGenerator) 

Generates a Quick Response code (two-dimensional barcode) from input data.
Parameters
*inputMessage*
The data to be encoded as a QR code. AnNSData
object whose display name is Message.

*inputCorrectionLevel*
A single letter specifying the error correction format. AnNSString
object whose display name is CorrectionLevel.
Default value:M

Discussion
    Generates an output image representing the input data according to the ISO/IEC 18004:2006 standard. The width and height of each module (square dot) of the code in the output image is one point. To create a QR code from a string or URL, convert it to an[NSData](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html#//apple_ref/occ/cl/NSData)object using the[NSISOLatin1StringEncoding](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/c/econst/NSISOLatin1StringEncoding)string encoding.
The*inputCorrectionLevel*
  parameter controls the amount of additional data encoded in the output image to provide error correction. Higher levels of error correction result in larger output images but allow larger areas of the code to be damaged or obscured without. There are four possible correction modes (with corresponding error resilience levels):
L : 7%
M : 15%
Q : 25%
H : 30%

Member Of
CICategoryBuiltIn
,CICategoryStillImage
,CICategoryGenerator
Sample Output
 **Figure 91**The result of using the CIQRCodeGenerator filter ![image: ../Art/CIQRCodeGenerator.pdf](https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/Art/CIQRCodeGenerator_2x.png)

这里也就是说

[qrFilter setValue:@"L" forKey:@"inputCorrectionLevel"];
[qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];
[qrFilter setValue:@"Q" forKey:@"inputCorrectionLevel"];
[qrFilter setValue:@"H" forKey:@"inputCorrectionLevel"];

这4中设置导致在二维码添加logo的允许所占大小是不一样的。

L

当我们设置 inputCorrectionLevelL 时,二维码可污染面积最小,此时二维码的密度最稀,如果二维码中的内容非常丰富时,建议用L设置,如果还想在二维码中添加logo,logo所在面积不超过二维码图片面积的7%,如果超过这个比例,就会导致图片无法识别

微信二维码图片长按 无法识别问题解析_第2张图片
121524462762_.pic_hd.jpg

M

递增

Q

递增

H

当我们设置 inputCorrectionLevelH 时,二维码可污染面积最小,此时二维码的密度最密,如果二维码中的内容比较简单,建议用H设置,如果还想在二维码中添加logo,logo所在面积不超过二维码图片面积的30%,如果超过这个比例,就会导致图片无法识别

微信二维码图片长按 无法识别问题解析_第3张图片
131524462830_.pic_hd.jpg

问题解决

所以最终解决方法

[qrFilter setValue:@"L" forKey:@"inputCorrectionLevel"];

且尽量不要在二维码中添加图片。

你可能感兴趣的:(微信二维码图片长按 无法识别问题解析)