QrCodeScanner掃碼工具(融合Zxing和Zbar庫,掃碼效率奇高)

融合Zxing和Zbar庫,對條形碼二維碼高兼容,掃碼效率奇高!

開發背景

前段采用Zxing和Zbar掃碼庫掃碼時,發現針對二維碼和條形碼,兩個庫有不同的效果,Zxing能高效精準識別二維碼,但在條形碼上卻不盡人意,在某些手機死活識別不出來;而后采用Zbar庫,在條形碼上效果杠杠的,而二維碼相對Zxing就遜色很多了。根據這些情況,我就覺得有必要搞個'萬金油',把兩者優勢融合起來,于是結合Zxing二維碼算法和Zbar條形碼算法的QrCodeScanner掃碼工具就憑空而出。

開發工作

比對了Zxing和Zbar兩個掃碼Demo,Zxing的相機掃描部分算是做得比較精良,Zbar就不想說了,最后決定采用Zxing掃描部分的代碼,但是也有很多地方與需求不符,所以結合網上資料和自己的分析,修改了其中的代碼。然后整個識別算法代碼是放在C層的。下面就將幾個核心部分列舉出來。

1.調整掃描采樣區域,優化取圖速度

在CameraManager類中不改變掃碼框大小,但是增加采樣區域大小,我這里是根據屏幕寬度作為邊長,截取中間正方形為取圖區域。

public Rect getRealFramingRect() {
    if (realFramingRect == null) {
        //獲取屏幕大小,然后根據屏幕寬度由中間截取于寬度等長的正方形
        Point screenResolution = configManager.getScreenResolution();
        int leftOffset = 0;
        int topOffset = (screenResolution.y - screenResolution.x) / 2;
        Rect rect = new Rect(leftOffset, topOffset, screenResolution.x,
                screenResolution.x+topOffset);
        
        //根據圖片分辨率和屏幕分辨率截取實際大小的圖片區域
        Point cameraResolution = configManager.getCameraResolution();
        rect.left = rect.left * cameraResolution.y / screenResolution.x;
        rect.right = rect.right * cameraResolution.y / screenResolution.x;
        rect.top = rect.top * cameraResolution.x / screenResolution.y;
        rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
        realFramingRect = rect;
    }
    return realFramingRect;
}
2.獲取適配的攝像頭預覽圖片,防止圖片拉伸

在CameraConfigurationManager類中獲取攝像頭所有預覽尺寸,根據屏幕分辨率選取最適合的預覽尺寸。

private static Point findBestPreviewSizeValue(
    CharSequence previewSizeValueString, Point screenResolution) {
    int bestX = 0;
    int bestY = 0;
    int diff = Integer.MAX_VALUE;
    //previewSizeValueString為包含所有預覽尺寸的字符串
    for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) {
        previewSize = previewSize.trim();
        int dimPosition = previewSize.indexOf('x');
        if (dimPosition < 0) continue;
        try {
            int newX = Integer.parseInt(previewSize.substring(0, dimPosition));
            int newY = Integer.parseInt(previewSize.substring(dimPosition + 1));
            int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y);
            if (newDiff == 0) {
                bestX = newX;bestY = newY;
                break;
            } else if (newDiff < diff) {
                bestX = newX;bestY = newY;diff = newDiff;
            }
        } catch (NumberFormatException nfe) {
            continue;
        }
    }
    if (bestX > 0 && bestY > 0) {
        return new Point(bestX, bestY);
    }
    return null;
}
3.旋正攝像頭獲取的YUV圖片數據,供識別庫識別

攝像頭獲取的圖片都是橫屏的,所以對圖片識別前,我們必須把圖片旋正過來,否則就無法正確識別。這個的圖片是YUV格式數據,其中"Y"表示明亮度(Lumina nce或Luma),也就是灰階值;而"U"和"V"表示的則是色度(Chrominance或Chroma),而在識別時,只取Y部分的數據就可以了,相當于把圖片灰度化。而為了提高計算效率,我把這部分代碼放在C層中實現了。

char* buffer = (char*) env->GetByteArrayElements(data, JNI_FALSE);
char*rotateData = new char[dataWidth * dataHeight];
for(int y = 0; y < dataHeight; y++) {
    for (int x = 0; x < dataWidth; x++) {
        rotateData[x * dataHeight + dataHeight - y - 1] = buffer[x + y * dataWidth];
    }
}
int tmp = dataWidth;
dataWidth = dataHeight;
dataHeight = tmp;
4.融合ZBar和Zxing庫,整個算法部分用NDK實現。

同樣是為了提高運算效率,我把兩部分的算法代碼都放在C層實現了,Zbar采用官方的C庫,Zxing采用C++庫,去掉兩個庫多余的代碼,精簡代碼結構,封裝公共部分代碼,從而實現識別運算上的優化。

關于整個項目的優化點還有好多,這里就不一一列舉了,這里已經將全部代碼放上去了,可以直接通過代碼來查看。

使用說明

1.使用Android Studio開發,配置Cmake環境

這里通過Cmake來編譯Native部分代碼,所以編譯時需要配置Cmake工具。如果不修改jni接口(DecodeEntry.cpp),也可以直接使用本項目提供的.so庫,把extraLib文件夾中的.so文件復制到項目lib目錄下即可。

2.修改識別模式

目前識別模式有三種,只識別二維碼,只識別條形碼,識別二維碼加條形碼(默認)??梢愿鶕约盒枨筮x擇不同模式,有利于提高識別效率。通過BarcodeFormat類進行修改。

    barcodeFormat = new BarcodeFormat();
    barcodeFormat.add(BarcodeFormat.BARCODE);
    barcodeFormat.add(BarcodeFormat.QRCODE);

然后作為參數傳進CaptureActivityHandler對象中。

handler = new CaptureActivityHandler(this, barcodeFormat);

源碼地址:

https://github.com/heiBin/QrCodeScanner

Demo地址:

https://github.com/heiBin/QrCodeScanner/raw/master/QrCodeScanner.apk

(操作補充說明):

直接使用編譯好的.so文件:
ZlVbuXS2ViNEwKwkJzzeZw==.png

如上圖所示,在app-main下加入jniLibs目錄,把extraLib下編譯好的.so文件全部復制過來;然后如上圖把build.gradle下的cmake相關代碼注釋掉。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容

  • 1. 二維碼掃碼庫介紹 二維碼又稱QR Code,QR全稱Quick Response,是一個近幾年來移動設備上超...
    Jinwong閱讀 12,417評論 1 40
  • Swift版本點擊這里歡迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh閱讀 25,493評論 7 249
  • Android中用于二維碼相關的庫比較少,并且大多數已經不再維護(具體可見https://android-arse...
    Trainee閱讀 19,971評論 3 17
  • 剛剛讀古典老師的書,看到里面寫道:未來有可能沒有專業。因為很多專業都是多元、綜合和跨學科的,不再像現在是單一學科的...
    營養私教西西閱讀 308評論 0 0
  • 幼兒園時光短暫而漫長,短暫的現在只剩下幾個畫面,漫長地那些畫面時時縈繞在我腦海中。關于幼兒園,最有趣的是在我還沒有...
    寅穎閱讀 1,678評論 0 0