【问题标题】:CIDetectorTypeQRCode fails to scan transparent imagesCIDetectorTypeQRCode 无法扫描透明图片
【发布时间】:2019-06-19 12:07:48
【问题描述】:

我正在尝试扫描用户从磁盘中选择的 QR 图像。我发现了一个奇怪的问题,我尝试的所有库都失败了(ZXING 或 ZBAR 的 CIDetector 旧端口)。 我知道有一些方法可以添加白色背景(例如重绘图像或使用 CIFilter),以便扫描图像。

扫描透明背景二维码的正确方法是什么(配置CIContext或CIDetector)。 (下图无法在 iOS 和 macOS 上扫描)。

https://en.wikipedia.org/wiki/QR_code#/media/File:QR_code_for_mobile_English_Wikipedia.svg

- (void)scanImage:(CIImage *)image
{
    NSArray <CIFeature *>*features = [[self QRdetector] featuresInImage:image];
    NSLog(@"Number of features found: %lu", [features count]);
}

- (CIDetector *)QRdetector
{
    CIContext *context = [CIContext contextWithOptions:@{kCIContextWorkingColorSpace : [NSNull null]}]; //no difference using special options or nil as a context

    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:context options:@{CIDetectorAccuracy : CIDetectorAccuracyHigh, CIDetectorAspectRatio : @(1)}];
    return detector;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSURL *URL = [[NSBundle mainBundle] URLForResource:@"transparentqrcode" withExtension:@"png"];
    UIImage *image = [UIImage imageWithContentsOfFile:[URL path]];

    CIImage *ciImage = [CIImage imageWithContentsOfURL:URL];

    //CUSTOM CODE TO ADD WHITE BACKGROUND
    CIFilter *filter = [CIFilter filterWithName:@"CISourceAtopCompositing"];
    [filter setDefaults];
    CIColor *whiteColor = [[CIColor alloc] initWithColor:[UIColor whiteColor]];
    CIImage *colorImage = [CIImage imageWithColor:whiteColor];

    colorImage = [colorImage imageByCroppingToRect:ciImage.extent];
    [filter setValue:ciImage forKey:kCIInputImageKey];
    [filter setValue:colorImage forKey:kCIInputBackgroundImageKey];
    CIImage *newImage = [filter valueForKey:kCIOutputImageKey];


    [self scanImage:ciImage];
    return YES;
}

【问题讨论】:

  • 如果我使用您的确切代码,以及您提供的透明图像,并将[self scanImage:ciImage]; 更改为[self scanImage:newImage];,我会找到 1 个功能,其中包含 @987654328 的.messageString @
  • 我在后期处理中添加了白色背景的cmets中写着。结果 newImage 没有透明背景。我的问题更像是为什么我需要使用任何后处理。如果有办法将 CIDetector 配置为开箱即用。
  • 啊,对不起...以为你的意思是它失败了即使添加了白色背景。
  • 有趣...快速测试似乎表明CIDetector 将 alpha 通道视为black...如果我编辑您的 QRCode 图像并将其更改为黑色以外的任何内容(保留透明领域原样),我得到了成功的结果。
  • 也很有趣——或者好奇?我尝试了几个在线二维码扫描仪(上传图像进行扫描)。一对夫妇返回了原始“黑色+透明”图像的正确值,但是当我上传“白色+透明”版本时失败。因此,看起来这些网站正在通过将 Alpha 通道填充/转换为白色进行预处理。

标签: ios macos ciimage cidetector


【解决方案1】:

正如 cmets 中所述,CIDetector 似乎将 Alpha 通道视为黑色。将其替换为白色作品 --- 除非 QRCode 本身是具有透明背景的白色。

我没有进行任何分析以查看这是否会更快,但它可能是一个更好的选择。

- (IBAction)didTap:(id)sender {

    NSURL *URL = [[NSBundle mainBundle] URLForResource:@"transparentqrcode" withExtension:@"png"];

    CIImage *ciImage = [CIImage imageWithContentsOfURL:URL];

    NSArray <CIFeature *>*features = [self getImageFeatures:ciImage];

    // if CIDetector failed to find / process a QRCode in the image,
    // (such as when the image has a transparent background),
    // invert the colors and try again
    if (features.count == 0) {
        CIFilter *filter = [CIFilter filterWithName:@"CIColorInvert"];
        [filter setValue:ciImage forKey:kCIInputImageKey];
        CIImage *newImage = [filter valueForKey:kCIOutputImageKey];
        features = [self getImageFeatures:newImage];
    }

    if (features.count > 0) {
        for (CIQRCodeFeature* qrFeature in features) {
            NSLog(@"QRFeature.messageString : %@ ", qrFeature.messageString);
        }
    } else {
        NSLog(@"Unable to decode image!");
    }

}

- (NSArray <CIFeature *>*)getImageFeatures:(CIImage *)image
{
    NSArray <CIFeature *>*features = [[self QRdetector] featuresInImage:image];
    NSLog(@"Number of features found: %lu", [features count]);
    return features;
}

- (CIDetector *)QRdetector
{
    CIContext *context = [CIContext contextWithOptions:@{kCIContextWorkingColorSpace : [NSNull null]}]; //no difference using special options or nil as a context

    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:context options:@{CIDetectorAccuracy : CIDetectorAccuracyHigh, CIDetectorAspectRatio : @(1)}];
    return detector;
}

【讨论】:

  • 我填写了一份错误报告。 rdar://47548370 这个解决方案有效,但我不觉得反转是比添加白色背景更好的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
  • 2021-04-13
  • 2013-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多