二维码扫描使用最多的主要有两个库:zbarSDK 和zxing
关于zbar的使用比较简单,在这里不多说了,对于zxing的使用就比较麻烦,虽然网上有很多关于zxing的使用方法,不过查了很多中文和英文的贴子。发现说的都不够详细,对与像我这样第一次搞的新手来说差一步就错了很多!
现在根据自己项目中使用的情况,详细具体的总结一下如何将ZXing集成到已有的iOS工程中
第一步:首先去Google Code或Github将ZXing的代码下载下来(ZXing(Github镜像地址)),整个工程比较大,我们只需要其中涉及iOS的部分,所以最好做一些裁剪。简单来说,我们只需要保留cpp和iphone这2个文件夹,其余的全部删掉。如下图所示:
第二步:裁剪,对于cpp这个目录,只保留cpp/core/src/zxing下面的内容,其余内容也可以删掉了。同样对iphone这个目录只需要保存 iphone/ZXingWidget/下面的内容,但是整个目录结构必须保持原样。裁剪完后,整个目录结构如下所示:
第三步:首先将修该后的zxing上面的开发包(即上面修改后的zxing文件夹),拷贝到你的项目根文件夹下面;
添加文件到你的工程中,选择“Add filesto...”,在弹出的框中,找到:你的项目文件夹/zxing/iphone/ZXingWidget下面的ZXingWidget.xcodeproj,选择"ZXingWidget.xcodeproj",在添加前,请先运行该项目,进行编译,如果成功,再进行此步添加!
添加成功后项目结构如下图:
第四步:选择你的项目--TARGETS--Build Phases---Target Dependencies----然后点击"+"添加“ZXingWidget”。添加后如下图:
第五步:
同样,添加frameWorks.方法:Build Phases---Target Dependencies----”Link Binary With Libraries”---点击"+"。添加如下几项:
libZXingWidget.a
AddressBook
AddressBookUI
AudioToolbox
AVFoundation
CoreMedia
CoreVideo
libiconv.dylib
完成后如下图:
第六步:后一步,在设置中增加如下2个header search path:
1. BuildSettings --- 2.搜索"header search paths" --- 3.双击"HeaderSearch Paths"
/zxing/iphone/ZXingWidget/Classes
./zxing/cpp/core/src
需要注意的是,第一个path要设置成循环查找子目录,而第二个不循环查找,如下图所示:
完成这一步,就已经完成了ZXing库的集成工作,(如果不做修改的话,zxing暂时只能识别二维码,不能识别条形码)
在这里编译工程,应该能成功,不会报错,如果有报错信息等,看看是否是少添加了库,Header Search Paths中的路径是否正确;
在项目中引用
首先将你使用ZXingWidgetController的文件的后缀该为.mm, 例如:我在MyZxingViewController.m改为:MyZxingViewController.mm否则在使用的时候会报:xxx filenot found的类似的问题
同时你必须将 #import
#import
#import
MyZxingViewController文件夹中引用
.h
#import |
#import "ZXingWidgetController.h" |
//#import "QRCodeReader.h"//这个引用在.h文件中为出错:iostream file not found |
@interface Contact : UIViewController |
UITextView *resultsView; |
NSString *resultsToDisplay; |
} |
@property (retain, nonatomic) IBOutlet UITextView *resultsView; |
@property (nonatomic, copy) NSString *resultsToDisplay; |
- (IBAction)scanPressed:(id)sender; @end |
具体用法可以参考ZXing(Github镜像地址)中的例子
修改zxing 使其能扫描条形码
例子中的代码确实只能做二维码的识别, 不能做条形码的扫描。 研究了一下又在网上找了一下, 结果发现稍做修改,还是可以让ZXing支持条形码和二维码的同时识别的, 代码稍侯就贴出来。本人亲自试过,确实可行。
总结地来说, ZBar使用起来比ZXing相对方便一点, 也就是更像是 卡片机与单反相机的区别。但如果需要修改代码的话,做一些自定义什么的,建议使用ZXing, 如果只是想随便用用的话, 建议使用ZBar.
好,话不多说, 下面说说如何使ZXing改改后可以支持扫条形码。
1.在- (IBAction)scanPressed:(id)sender方法中:
ZXingWidgetController*widController = [[ZXingWidgetControlleralloc] initWithDelegate:selfshowCancel:YESOneDMode:YES];
MultiFormatOneDReader*OneReaders=[[MultiFormatOneDReader alloc]init];
QRCodeReader* qrcodeReader = [[QRCodeReader alloc] init];
NSSet*readers = [[NSSet alloc] initWithObjects:OneReaders,qrcodeReader,nil];
[qrcodeReader release];[OneReaders release];
2.在ZXingWidgetController.m的(void)captureOutput:(AVCaptureOutput *)captureOutput :方法中,注释掉以下方法
if(oneDMode) {
// let's just give the decoder a vertical band right above the red line
cropRect.origin.x = cropRect.origin.x + (cropRect.size.width / 2) - (ONE_D_BAND_HEIGHT + 1);
cropRect.size.width = ONE_D_BAND_HEIGHT;
// do a rotate
CGImageRef croppedImg = CGImageCreateWithImageInRect(capture, cropRect);
capture = [selfCGImageRotated90:croppedImg];
capture = [selfCGImageRotated180:capture];
// UIImageWriteToSavedPhotosAlbum([UIImage imageWithCGImage:capture], nil, nil, nil);
CGImageRelease(croppedImg);
cropRect.origin.x = 0.0;
cropRect.origin.y = 0.0;
cropRect.size.width = CGImageGetWidth(capture);
cropRect.size.height = CGImageGetHeight(capture);
}
3. 将上面注释掉的代码向下数大概约20行处的代码:UIImage *scrn = [[UIImage alloc] initWithCGImage:newImage]; 改为:int backCameraImageOrientation = UIImageOrientationRight; UIImage *scrn = [[UIImage alloc] initWithCGImage:newImage scale: (CGFloat)1.0 orientation:backCameraImageOrientation];
4. 在OverlayView.m注释代码以下代码:
self.oneDMode = isOneDModeEnabled;
然后运行 , 会发现可扫条形码了 , 还可以同时扫二维码了