前言
ZXing库是一个专门用来解析多种二维码和条形码(包括包括 QR Code、Aztec Code、UPC、EAN、Code 39、Code 128等)的开源性质的处理库,而ZingObjC库是它的一个移植版本。由于博主还没有真机进行调试,所以舍去了使用摄像头的一些方法,仅实现其最终识别结果的方法。
一、实现步骤
使用ZXingObjC库完整的步骤分为以下六步:
- 为项目工程导入ZXingObjC库,可以在GitHub上直接搜索下载也可以使用Cocoa Pods进行安装
- 在需要使用ZXingObjC库的地方引入头文件
#import <ZXingObjC/ZXingObjC.h>
- 创建扫描头,也就是创建一个 ZXCapture 对象,该对象负责管理扫描的整个过程。可以设置代理来接收扫描结果
self.capture = [[ZXCapture alloc] init]; self.capture.delegate = self;
- 配置扫描界面,可以设置扫描界面的样式和布局,例如扫描框的样式、扫描线的颜色等
self.capture.layer.frame = self.view.bounds; [self.view.layer addSublayer:self.capture.layer];
- 开始扫描:调用 ZXCapture 对象的 start 方法开始扫描
[self.capture start];
- 处理扫描结果:通过实现 ZXCaptureDelegate 协议中的方法来处理扫描结果。例如:
- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result { if (result) { NSString *contents = result.text; // 处理扫描到的内容 } }
二、扫描界面和扫描框的样式
1.扫描界面
- 设置扫描界面的背景色:通过修改 capture.layer.backgroundColor 属性来改变扫描界面的背景颜色
- 设置扫描线的颜色:通过修改 capture.layer.scanColor 属性来改变扫描线的颜色
- 设置扫描线的样式:通过修改 capture.layer.scanLineStyle 属性来改变扫描线的样式,可选值包括线条、网格等。
- 设置扫描区域的方向:通过修改 capture.camera 的 orientation 属性来设置扫描区域的方向,例如横向或纵向扫描
- 设置扫描速度和精度:可以通过capture.rotation属性来设置扫描的速度和精度,值越大速度越快精度也就越低
2.扫描框
- 设置扫描框的位置和大小:通过修改 capture.layer.scanRect 属性来设置扫描框的位置和大小,以相对于扫描界面的比例表示
- 设置扫描框的颜色和边框:可以使用 UIView 来创建一个矩形视图,并设置它的背景色和边框样式来实现扫描框的外观。
- 设置扫描框的角标样式:可以使用 CALayer 的 cornerRadius 和 borderWidth 属性来设置扫描框的角标样式。
三、实现步骤
这里我是用来实现识别以图片形式传入的条形码
实现解码的步骤总共分为以下这几步:
- 将传入的UIImage对象作为转换为成CGImageRef对象,然后使用 ZXCGImageLuminanceSource 创建一个 ZXLuminanceSource 对象来提供图像数据
- 使用 ZXHybridBinarizer 对象对图像进行二值化处理,创建一个 ZXBinaryBitmap对象用于后续的解码
- 创建一个 ZXDecodeHints 对象,用于配置解码器的选项。这里使用了默认的选项。然后创建一个 ZXMultiFormatReader****对象,用来条形码解码
- 最后,调用 decode: 方法对图像进行解码,返回解码结果ZXResult对象
- (NSString*)recognizeBarcodeInImage:(UIImage *)image {
CGImageRef cgImage = image.CGImage;
ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:cgImage];
ZXBinaryBitmap *bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]];
NSError *error = nil;
ZXDecodeHints *hints = [ZXDecodeHints hints];
ZXMultiFormatReader *reader = [ZXMultiFormatReader reader];
ZXResult *result = [reader decode:bitmap hints:hints error:&error];
if (result) {
NSString *barcodeValue = result.text;
NSLog(@"扫描到的条形码: %@", barcodeValue);
} else {
NSLog(@"条形码识别出错: %@", error);
}
return result.text;
}
下面是用解码的信息进行简单的网络请求
- (void)networkGetBarcodeData:(NSString*)querysData {
NSString *encodedString = [querysData stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSString *urlString = [NSString stringWithFormat:@"此处为API接口/%@", encodedString];
NSURL* url = [NSURL URLWithString:urlString];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
NSURLSession* session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:^(NSData * _Nullable body , NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
NSString *bodyString = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
NSDictionary *bodyDictionary = [NSJSONSerialization JSONObjectWithData:body options:kNilOptions error:nil];
NSDictionary* dataDictionary = bodyDictionary[@"data"];
//打印应答中的body
NSLog(@"Response body: %@" , bodyString);
NSString* brand = dataDictionary[@"trademark"];
NSString* name = dataDictionary[@"goodsName"];
NSLog(@"brand:%@", brand);
NSLog(@"name:%@", name);
NSString* medicineName = [NSString stringWithFormat:@"%@", name];
self.myBarcodeValue = medicineName;
dispatch_async(dispatch_get_main_queue(), ^{
self.medicineLabel.text = self.myBarcodeValue;
});
} else {
NSLog(@"错误是%@",error);
}
}];
[task resume];
}
运行结果如下: