iOS 8以上可以使用系统原生的识别方法就行了:
CIDetector*detector = [CIDetectordetectorOfType:CIDetectorTypeQRCodecontext:niloptions:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
NSData*imageData =UIImagePNGRepresentation(newImage);
CIImage*ciImage = [CIImageimageWithData:imageData];
NSArray*features = [detectorfeaturesInImage:ciImage];
CIQRCodeFeature*feature = [featuresobjectAtIndex:0];
NSString*scannedResult = feature.messageString;
[selfhandelStringValue:scannedResult];
但是需要兼容iOS7的应用就需要使用Google的zxing来识别了,代码也很简单
UIImage*loadImage= img;
CGImageRefimageToDecode = loadImage.CGImage;
ZXLuminanceSource*source = [[ZXCGImageLuminanceSourcealloc]initWithCGImage:imageToDecode];
ZXBinaryBitmap*bitmap = [ZXBinaryBitmapbinaryBitmapWithBinarizer:[ZXHybridBinarizerbinarizerWithSource:source]];
NSError*error =nil;
ZXDecodeHints*hints = [ZXDecodeHintshints];
ZXMultiFormatReader*reader = [ZXMultiFormatReaderreader];
ZXResult*result = [readerdecode:bitmap
hints:hints
error:&error];
if(result) {
NSString*contents = result.text;
}
不过,在实际使用时发现,从相机拍摄的图片识别不出来,不管使用原生的还是zxing,都识别不出来,所以肯定不是框架的问题了,后来找了很久,看到一个网友的答复比较准确
zxing 之所以不好用是需要做优化的。
图片大小不能完全按照原始的尺寸来,我测试过,把图片缩小成 256 像素左右识别率比较高。目前不清楚是什么原理。
还有二维码的图像识别算法, GlobalHistogramBinarizer 和 HybridBinarizer 分别适用不同的场景,图片识别的话要看图片属于什么类型的,黑白的肯定是前者识别更有效,带有渐变的或者有阴影的则采用后一个算法。
总之二维码识别有许多层级的优化,目前正在研究中。
按照这个说法,我又写了一个压缩图片的方法
UIImage* bigImage = theImage;
floatactualHeight = bigImage.size.height;
floatactualWidth = bigImage.size.width;
floatnewWidth =0;
floatnewHeight =0;
if(actualWidth > actualHeight) {
//宽图
newHeight =256.0f;
newWidth = actualWidth / actualHeight * newHeight;
}
else
{
//长图
newWidth =256.0f;
newHeight = actualHeight / actualWidth * newWidth;
}
CGRectrect =CGRectMake(0.0,0.0, newWidth, newHeight);
UIGraphicsBeginImageContext(rect.size);
[bigImagedrawInRect:rect];// scales image to rect
theImage =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//RETURN
returntheImage;
图片压缩过后,识别的速度明显提升了,而且基本上都能识别出来,至此,问题解决。
题外话
原生扫描在扫描的时候,如果同时扫描二维码和条形码,识别条形码的效率很低下,如果需求明确要求要同时扫描的话就不知道有什么好的解决方案了,我看了下微信是不存在这个问题的,但是如果只识别条形码的话,速度还是很快的。所以如果可以,尽量区分开,对于识别的效率有利于提高。
另外,如果有好的解决方案,希望不吝分享~~~