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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zyzxrj/article/details/47723121

现在很多项目中都会用到扫码这个功能,现在开源框架被大家熟知的有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大片扫描区域与一块扫描区域,发现一小块的聚焦效果更好,更清晰,扫描速度更快,我对比过微信跟淘宝的扫描,发现都非常清晰,当然我也不知道他们用什么技术实现的



猜你喜欢

转载自blog.csdn.net/zyzxrj/article/details/47723121