天天看點

Zbar實作微信掃描界面可支援64位,可掃描二維碼條形碼1、引入頭檔案2、導入要用到的framework3、ZBarReaderView添加掃碼框 7、設定ZBar的掃描焦點scanCrop

現在很多項目中都會用到掃碼這個功能,現在開源架構被大家熟知的有Zbar以及ZXIng,Zbar底層是C語言來實作的,掃碼速度比ZXing要快很多,是以我在項目中選擇的是Zbar掃碼。

對應代碼csdn的下載下傳位址:ZBar仿微信條形碼二維碼掃描界面

先上我寫好的界面:

Zbar實作微信掃描界面可支援64位,可掃描二維碼條形碼1、引入頭檔案2、導入要用到的framework3、ZBarReaderView添加掃碼框 7、設定ZBar的掃描焦點scanCrop

ZBar為我們提供了兩種使用方式,一種是直接使用ZBar提供的ZBarReaderViewController打開一個掃描界面,另一種方式是使用ZBar提供的可以嵌在其他視圖中的ZBarReaderView,實際項目中我們更可能會使用第二種方式,這可以讓我們對界面做更多的定制。這裡我詳細說一下使用ZBarReaderView這種方式實作掃碼功能:

1、引入頭檔案

Zbar實作微信掃描界面可支援64位,可掃描二維碼條形碼1、引入頭檔案2、導入要用到的framework3、ZBarReaderView添加掃碼框 7、設定ZBar的掃描焦點scanCrop

将git上下載下傳的ZBarSDK頭檔案拖入項目中,勾選copy選項

2、導入要用到的framework

選中自己建好的項目,然後切換到General->Linked Frameworks and Libraries點選小+号添加需要的架構,假如項目中已經有的framework無需重複添加

Zbar實作微信掃描界面可支援64位,可掃描二維碼條形碼1、引入頭檔案2、導入要用到的framework3、ZBarReaderView添加掃碼框 7、設定ZBar的掃描焦點scanCrop

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在掃描的時候會自動出現訓示框,一個綠色的正方形,是以我覺根本沒必要添加掃描線之類的,當然如果你需要我下面的代碼裡面也有寫,界面如下:

Zbar實作微信掃描界面可支援64位,可掃描二維碼條形碼1、引入頭檔案2、導入要用到的framework3、ZBarReaderView添加掃碼框 7、設定ZBar的掃描焦點scanCrop

左下角是掃描是截獲的圖檔,右邊是掃描到的字元串(可掃二維碼以及條形碼,二維碼掃碼速度更快)

這個界面是用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實作微信掃描界面可支援64位,可掃描二維碼條形碼1、引入頭檔案2、導入要用到的framework3、ZBarReaderView添加掃碼框 7、設定ZBar的掃描焦點scanCrop

但是Zbar的scanCrop就要參照下面的坐标系,整個螢幕區域就是(0,0,螢幕高度,螢幕寬度),紅色區域為(0,螢幕寬度 - 0 - 200,100,200)

Zbar實作微信掃描界面可支援64位,可掃描二維碼條形碼1、引入頭檔案2、導入要用到的framework3、ZBarReaderView添加掃碼框 7、設定ZBar的掃描焦點scanCrop

  計算出來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大片掃描區域與一塊掃描區域,發現一小塊的聚焦效果更好,更清晰,掃描速度更快,我對比過微信跟淘寶的掃描,發現都非常清晰,當然我也不知道他們用什麼技術實作的