您的位置:首页 > 移动开发 > 微信开发

Zbar实现微信扫描界面可支持64位,可扫描二维码条形码

2015-08-17 13:21 645 查看
现在很多项目中都会用到扫码这个功能,现在开源框架被大家熟知的有Zbar以及ZXIng,Zbar底层是C语言来实现的,扫码速度比ZXing要快很多,所以我在项目中选择的是Zbar扫码。

对应代码csdn的下载地址:ZBar仿微信条形码二维码扫描界面

先上我写好的界面:



ZBar为我们提供了两种使用方式,一种是直接使用ZBar提供的ZBarReaderViewController打开一个扫描界面,另一种方式是使用ZBar提供的可以嵌在其他视图中的ZBarReaderView,实际项目中我们更可能会使用第二种方式,这可以让我们对界面做更多的定制。这里我详细说一下使用ZBarReaderView这种方式实现扫码功能:

1、引入头文件



将git上下载的ZBarSDK头文件拖入项目中,勾选copy选项

2、导入要用到的framework

选中自己建好的项目,然后切换到General->Linked Frameworks and Libraries点击小+号添加需要的框架,假如项目中已经有的framework无需重复添加



3、ZBarReaderView添加扫码框

首先我们自定义扫码框为页面的一部分,代码如下:

- (void) init_camera
{
ZBarReaderView * reader = [ZBarReaderView new];
ZBarImageScanner * scanner = [ZBarImageScanner new];
[scanner setSymbology:ZBAR_PARTIAL config:0 to:0];
[reader initWithImageScanner:scanner];
[scanner release];
reader.readerDelegate = self;

const float h = [UIScreen mainScreen].bounds.size.height;
const float w = [UIScreen mainScreen].bounds.size.width;
const float h_padding = w / 10.0;
const float v_padding = h / 10.0;
CGRect reader_rect = CGRectMake(h_padding, v_padding,
w - h_padding * 2.0, h / 3.0);//视图中的一小块
reader.frame = reader_rect;
reader.backgroundColor = [UIColor redColor];
[reader start];

[self.view addSubview: reader];
[reader release];

}


代理方法实现:

- (void) readerView:(ZBarReaderView *)readerView didReadSymbols: (ZBarSymbolSet *)symbols fromImage:(UIImage *)image
{
ZBarSymbol * s = nil;
for (s in symbols)
{
text.text = s.data;
image_view.image = image;
break;
}
}


Zbar在扫描的时候会自动出现指示框,一个绿色的正方形,所以我觉根本没必要添加扫描线之类的,当然如果你需要我下面的代码里面也有写,界面如下:



左下角是扫描是截获的图片,右边是扫描到的字符串(可扫二维码以及条形码,二维码扫码速度更快)

这个界面是用xib直接拖出来的

除了readerView其他视图都是用xib直接拖出来的,大家自由发挥,只是一个例子


4、设置全屏模式的扫码框-如微信扫描的效果

我自定义了一个ZbarOverlayView,这个类做的就是盖在Zbar的扫描框上的显示效果:
/**
*  透明扫描框的区域
*/
@property (nonatomic, assign) CGSize transparentArea;
@property (nonatomic, assign) CGFloat tansparentY;
-(void)startAnimation;
-(void)stopAnimation;


上面是传入参数,中间透明框的大小,扫描框的起始高度,然后就是绿色闪烁线的开始结束动画方法,使用如下,在扫描界面添加如下代码:
_overLayView = [[ZbarOverlayView alloc]initWithFrame:reader.frame];//添加覆盖视图
//    [_overLayView startAnimation];
_overLayView.transparentArea = reader_rect.size;//设置中间可选框大小
[reader addSubview:_overLayView];
reader.scanCrop = [self getScanCrop:reader_rect readerViewBounds:reader_rect1];//CGRectMake(100 / h,0.1, 1/3.0,1.8)


5、绿色线条移动动画

设置staticNSTimeInterval kLineAnimateDuration = 0.02;
- (void)lineDrop
{
[UIView animateWithDuration:kLineAnimateDuration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
CGRect rect = _imgLine.frame;
rect.origin.y = _lineH;
_imgLine.frame = rect;
}completion:^(BOOL complite){
CGFloat maxBorder = _rectY + self.transparentArea.height - 4;
if (_lineH > maxBorder) {

_lineH = _rectY + 4;
}
_lineH ++;
}];
}


线条高度是2,让线条在方框内活动所以起始高度+4,最大高度-4


6、实现边缘透明遮罩,中间挖空的二维码扫描框

- (void)drawRect:(CGRect)rect {//viewDidLoad之后调用

//整个二维码扫描界面的颜色
CGRect screenDrawRect = self.frame;

//中间清空的矩形框
CGRect clearDrawRect = CGRectMake(screenDrawRect.size.width / 2 - self.transparentArea.width / 2,
_rectY,
self.transparentArea.width,self.transparentArea.height);

CGContextRef ctx = UIGraphicsGetCurrentContext();
[self addScreenFillRect:ctx rect:screenDrawRect];

[self addCenterClearRect:ctx rect:clearDrawRect];

[self addWhiteRect:ctx rect:clearDrawRect];

[self addCornerLineWithContext:ctx rect:clearDrawRect];
}


上面调用的四个方法都是自定义的,添加覆盖页面全屏的半透明效果,清空要留白的区域,添加白色矩形框,添加四个尖角绿色线条

7、设置ZBar的扫描焦点scanCrop

很多人可能会忽略这个属性,其实这个属性不设置也可以扫描出来,假如设置错误的用户可能会觉得不设置扫描还快一点,当然在我搞清楚这个属性之前我也不想使用这个属性,但是使用全屏扫描的用户可能都会有一个尴尬的地方,当有几个二维码在扫描范围内,明明扫描框在中间,可是却扫到了左下角的二维码,中间的确不扫描,这个明显是不合逻辑的。Zbar就给我们提供了这么一个属性。
scanCrop在Zbar的函数说明上要传入参数是 (0, 0, 1, 1),defaults to the full image (0, 0, 1, 1),也就是说默认是全屏扫描的。
ios开发者都知道苹果屏幕的坐标系是从左上角作为(0,0)点开始的,如下红色区域大小为(0,0,200,100)



但是Zbar的scanCrop就要参照下面的坐标系,整个屏幕区域就是(0,0,屏幕高度,屏幕宽度),红色区域为(0,屏幕宽度 - 0 - 200,100,200)


计算出来scanCrop为(0/屏幕高度,屏幕宽度
- 0 - 200/屏幕宽度,100/屏幕高度,200/屏幕宽度)

以下是我写的获取scanCrop的函数,rect传入空白框的区域大小,readerViewBounds传入全部扫描区域的大小:

-(CGRect)getScanCrop:(CGRect)rect readerViewBounds:(CGRect)readerViewBounds
{
CGFloat fullWidth = readerViewBounds.size.width;
CGFloat fullHeight = readerViewBounds.size.height;
CGFloat x,y,width,height;
x = rect.origin.x;
y = rect.origin.y;
width = rect.size.width;
height = rect.size.height;
if (x + width > fullWidth) {
if (width > fullWidth) {
width = fullWidth;
}else{
x = 0;
}
}
if (y + height > fullHeight) {
if (height > fullHeight) {
height = fullHeight;
}else{
y = 0;
}
}
CGFloat x1,y1,width1,height1;
x1 = (fullWidth - width - x) / fullWidth;
y1 = y / fullHeight;
width1 = width / fullWidth;
height1 = rect.size.height / readerViewBounds.size.height;

NSLog(@"frame:%@",NSStringFromCGRect(CGRectMake(y1, x1,height1, width1)));
return CGRectMake(y1, x1,height1, width1);
}


另外我对比过Zbar大片扫描区域与一块扫描区域,发现一小块的聚焦效果更好,更清晰,扫描速度更快,我对比过微信跟淘宝的扫描,发现都非常清晰,当然我也不知道他们用什么技术实现的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: