iOS中Zbar實現(xiàn)高效、快速條形碼掃描

背景

條形碼、二維碼是日常生活中用的較多的功能,我們在開發(fā)中之前用的都是ZXing、Zbar這兩個開源庫。不過在iOS7之后,蘋果系統(tǒng)自己實現(xiàn)了一套api,終于可以丟棄第三方,用上蘋果爸爸自己的功能了。

首先說說ZXing、Zbar這兩個開源庫。由于ZXing是用java實現(xiàn)的,Zbar是用C語音實現(xiàn)了,所以Zbar的識別效率遠遠高于ZXing,所以Zbar一般都是開發(fā)者的首選。不過iOS7系統(tǒng)出現(xiàn)自己的api后,系統(tǒng)的自然成為了首選。

按照識別速度來排序的話:系統(tǒng)api>Zbar>ZXing。系統(tǒng)的api識別速度非常的快,而且有效距離比其他兩個也大。最主要是系統(tǒng)自帶的api在識別條形碼的時候即使成90度垂直狀,仍然可以很快的識別出來。所以疑問來了,那就直接用系統(tǒng)api就行了唄。

話說本人也是這么想的,不過在實際過程中發(fā)現(xiàn)一個重大的問題!!有一些條形碼居然識別不了!經(jīng)過分析此條形碼的Code是EAN-128Code這是國內自己定義的,所以蘋果不支持。但是實際情況線下還挺多這種條形碼的,所以最后不得不換成Zbar。

Zbar脫坑記

Zbar的集成非常簡單,通過Cocopods直接導入即可。然后通過以下代碼使用

self.readerView = [[ZBarReaderView alloc] init];
self.readerView.frame = CGRectMake(0,0, preView.frame.size.width, preView.frame.size.height);
self.readerView.tracksSymbols = NO;
self.readerView.readerDelegate = self;
self.readerView.torchMode = 0;
self.readerView.allowsPinchZoom = NO;
ZBarImageScanner *scanner = self.readerView.scanner;
[scanner setSymbology:0 config:ZBAR_CFG_ENABLE to:0];
[scanner setSymbology:ZBAR_CODE128 config:ZBAR_CFG_ENABLE to:1];
[scanner setSymbology:ZBAR_CODE93 config:ZBAR_CFG_ENABLE to:1];
[scanner setSymbology:ZBAR_CODE39 config:ZBAR_CFG_ENABLE to:1];

很簡單,大功告成!

問題1

遇到第一個問題則是,發(fā)現(xiàn)同一個單號再次掃描反應非常遲鈍,而且掃描速度不是非常的快。這個時候點進去ZBarReaderView看了一下屬性。發(fā)現(xiàn)

// this flag still works, but its use is deprecated
@property (nonatomic) BOOL enableCache;

初步懷疑跟這個屬性有關,所以通過設置此屬性為NO,然后再次測試,發(fā)現(xiàn)此問題解決。同時掃描速度提速了

再次提速

雖然通過設置enableCache屬性能夠加快掃描速度,不過感覺還是有點慢,因為Zbar默認是全屏幕掃,即當條形碼出現(xiàn)在預覽框就可以識別到。

通過觀察屬性發(fā)現(xiàn)了scanCrop,縮小掃描區(qū)域

    self.readerView.scanCrop = CGRectMake((_previewH/2-150)/_previewH, 0, 300/_previewH, 1);//中間區(qū)域高度為300的掃描區(qū)域

這個掃描區(qū)域的設置要非常的注意。我們預覽框看到的圖片與實際圖片不一樣,它是一個90度放倒的圖片。說白了就是我們預覽框x、y坐標對應實際照片的y、x坐標;高對應寬,寬對應高。而且這里所有的值都是小于1的。scanCrop默認值是(0,0,1,1)所以會是全屏掃描

不過通過設置下來,近距離掃描確實已經(jīng)非常快了。但是滿足不了我們的要求。得離著20cm左右掃描速度非??欤x著遠了識別速度非常的慢,甚至識別不了。

ZBarReaderView所有的屬性都翻了一個遍,也沒有發(fā)現(xiàn)相關屬性。

最終迫不得已只能去翻看Zbar源碼,試試能不能改善了

終極優(yōu)化

在網(wǎng)上轉了一圈沒搜到相關信息,所以只能研究研究代碼。

通過翻看代碼發(fā)現(xiàn),其實Zbar可以通俗的講分成兩部分。通過1、通過預覽獲取圖片數(shù)據(jù);2、通過C語言核心邏輯去解析
第二步通過確認沒有問題,所以問題出在第一步。由于第一步其實有點老生常談,所以看了代碼之后馬上發(fā)現(xiàn)了問題。即ZBarReaderViewImpl_Capture代碼的實現(xiàn)

此代碼很多年沒有維護了,所以獲取預覽圖片的時候,也是按照當時設備最大分辨率設置。隨著時間的發(fā)展,設備分辨率也提高了非常多

原來代碼

if ([session canSetSessionPreset:AVCaptureSessionPreset640x480])
{
    [session setSessionPreset:AVCaptureSessionPreset640x480];
}
else if ([session canSetSessionPreset:AVCaptureSessionPreset352x288])
{
    [self.session setSessionPreset:AVCaptureSessionPreset352x288];
}

原來代碼支持圖片的分辨率最高是640*480非常的小

改后的代碼

if ([session canSetSessionPreset:AVCaptureSessionPreset1920x1080]) {
    [session setSessionPreset:AVCaptureSessionPreset1920x1080];
}
if ([session canSetSessionPreset:AVCaptureSessionPreset1280x720])
{
    [session setSessionPreset:AVCaptureSessionPreset1280x720];
}
else if ([session canSetSessionPreset:AVCaptureSessionPreset640x480])
{
    [session setSessionPreset:AVCaptureSessionPreset640x480];
}
else if ([session canSetSessionPreset:AVCaptureSessionPreset352x288])
{
    [self.session setSessionPreset:AVCaptureSessionPreset352x288];
}

我們增加了圖片的分辨率即可。此時可以高效、快速、遠距離的識別到條形碼了。

總結

解決這個問題也是循序漸進式,通過自己的努力最終解決了問題。當我們在使用第三方的代碼庫的時候,遇到問題還是要多看看源碼,只有這樣我們才能了然于胸。遇到問題解決起來也會游刃有余。

我的博客

FlyOceanFish

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容