iOS11以后才提供了相册识别条形码的功能。但是识别的时候,对清晰度和图片大小以及条形码在图片的位置都有严格的要求,所以经常失败。
解决思路:
1、压缩图片到合适的尺寸。
2、保证图片清晰。
3、为了保证条形码在中间位置,针对长图进行裁剪后的三次识别。
最终可以做到正常的条形码可以识别,长图的条形码在图顶部和尾部的也能识别。 但是拍摄模糊的就无能为力了。
/// 图片缩放到指定大小尺寸
- (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size {
// 创建一个bitmap的context
// 并把它设置成为当前正在使用的context
UIGraphicsBeginImageContext(size);
// 绘制改变大小的图片
[img drawInRect:CGRectMake(0, 0, size.width, size.height)];
// 从当前context中创建一个改变大小后的图片
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
// 使当前的context出堆栈
UIGraphicsEndImageContext();
// 返回新的改变大小后的图片
return scaledImage;
}
/*
图片剪裁接口
* 1.rect超过image.size则返回原图
* 2.rect可以是size的任何一个子集,比如取中间半区域 CG
*/
- (UIImage *)imageByCropToRect:(CGRect)rect originImg:(UIImage *)originImg {
rect.origin.x *= originImg.scale;
rect.origin.y *= originImg.scale;
rect.size.width *= originImg.scale;
rect.size.height *= originImg.scale; // pt -> px (point -> pixel)
if (rect.size.width <= 0 || rect.size.height <= 0) return nil;
CGImageRef imageRef = CGImageCreateWithImageInRect(originImg.CGImage, rect);
UIImage *image = [UIImage imageWithCGImage:imageRef scale:originImg.scale orientation:originImg.imageOrientation];
CGImageRelease(imageRef);
return image;
}
/// 获取缩放后的图片 -- 缩放到不太大的图片
- (UIImage *)getScaledImage:(UIImage *)originImg {
UIImage *img = originImg;
CGFloat maxSize = [UIScreen mainScreen].scale * 256.0; // 图片太小和太大都识别不了条形码
if (img.size.width > img.size.height) {
if (img.size.width < maxSize) {
return originImg;
}
img = [self scaleToSize:originImg size:CGSizeMake(maxSize, maxSize * (originImg.size.height/originImg.size.width))];
} else {
if (img.size.height < maxSize) {
return originImg;
}
img = [self scaleToSize:originImg size:CGSizeMake(maxSize * (originImg.size.width/originImg.size.height), maxSize)];
}
return img;
}
/// 获取上半部分图片
- (UIImage *)getScaledImageUp:(UIImage *)originImg {
UIImage *img = originImg;
CGFloat maxSize = [UIScreen mainScreen].bounds.size.height; // 图片太小和太大都识别不了条形码
CGFloat width = originImg.size.width;
CGFloat height = originImg.size.height;
if (img.size.width > img.size.height) {
width = maxSize/2.0;
height = maxSize * (originImg.size.height/originImg.size.width);
} else {
height = maxSize/2.0;
width = maxSize * (originImg.size.height/originImg.size.width);
}
img = [self imageByCropToRect:CGRectMake(0, 0, width, height) originImg:img];
return img;
}
/// 获取下半部分图片
- (UIImage *)getScaledImageDown:(UIImage *)originImg {
UIImage *img = originImg;
CGFloat maxSize = [UIScreen mainScreen].bounds.size.height; // 图片太小和太大都识别不了条形码
CGFloat width = originImg.size.width;
CGFloat height = originImg.size.height;
if (img.size.width > img.size.height) { // 宽图
width = maxSize/2.0;
height = maxSize * (originImg.size.height/originImg.size.width);
img = [self imageByCropToRect:CGRectMake(width, 0, width, height) originImg:img];
} else { // 高图
height = maxSize/2.0;
width = maxSize * (originImg.size.height/originImg.size.width);
img = [self imageByCropToRect:CGRectMake(0, height, width, height) originImg:img];
}
return img;
}