![](/img/trans.png)
[英]CIDetector with CIDetectorTypeQRCode works on iPad but not on iPhone and iPod
[英]CIDetectorTypeQRCode fails to scan transparent images
我正在嘗試掃描用戶從磁盤選擇的QR圖像。 我發現了一個奇怪的問題,即所有嘗試使用的庫都失敗了(CIDetector ZXING或ZBAR的舊端口)。 我知道有多種方法可以添加白色背景(例如重繪圖像或使用CIFilter),以便對圖像進行掃描。
掃描具有透明背景的QR碼的正確方法是什么(配置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;
}
如評論中所述, 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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.