1. 程式人生 > >Android開源庫之使用ZXing開源庫生成二維碼及識別本地二維碼圖片

Android開源庫之使用ZXing開源庫生成二維碼及識別本地二維碼圖片

/**
     * 解析二維碼(使用解析RGB編碼資料的方式)
     *
     * @param path
     * @return
     */
    public static Result decodeBarcodeRGB(String path) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inSampleSize = 1;
        Bitmap barcode = BitmapFactory.decodeFile(path, opts);
        Result result = decodeBarcodeRGB(barcode);
        barcode.recycle();
        barcode = null;
        return result;
    }

    /**
     * 解析二維碼 (使用解析RGB編碼資料的方式)
     *
     * @param barcode
     * @return
     */
    public static Result decodeBarcodeRGB(Bitmap barcode) {
        int width = barcode.getWidth();
        int height = barcode.getHeight();
        int[] data = new int[width * height];
        barcode.getPixels(data, 0, width, 0, 0, width, height);
        RGBLuminanceSource source = new RGBLuminanceSource(width, height, data);
        BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
        QRCodeReader reader = new QRCodeReader();
        Result result = null;
        try {
            result = reader.decode(bitmap1);
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (ChecksumException e) {
            e.printStackTrace();
        } catch (FormatException e) {
            e.printStackTrace();
        }
        barcode.recycle();
        barcode = null;
        return result;
    }
2、基於YUV方法
/**
     * 解析二維碼(使用解析YUV編碼資料的方式)
     *
     * @param path
     * @return
     */
    public static Result decodeBarcodeYUV(String path) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inSampleSize = 1;
        Bitmap barcode = BitmapFactory.decodeFile(path, opts);
        Result result = decodeBarcodeYUV(barcode);
        barcode.recycle();
        barcode = null;
        return result;
    }

    /**
     * 解析二維碼(使用解析YUV編碼資料的方式)
     *
     * @param barcode
     * @return
     */
    public static Result decodeBarcodeYUV(Bitmap barcode) {
        if (null == barcode) {
            return null;
        }
        int width = barcode.getWidth();
        int height = barcode.getHeight();
        //以argb方式存放圖片的畫素
        int[] argb = new int[width * height];
        barcode.getPixels(argb, 0, width, 0, 0, width, height);
        //將argb轉換為yuv
        byte[] yuv = new byte[width * height * 3 / 2];
        encodeYUV420SP(yuv, argb, width, height);
        //解析YUV編碼方式的二維碼
        Result result = decodeBarcodeYUV(yuv, width, height);

        barcode.recycle();
        barcode = null;
        return result;
    }

    /**
     * 解析二維碼(使用解析YUV編碼資料的方式)
     *
     * @param yuv
     * @param width
     * @param height
     * @return
     */
    private static Result decodeBarcodeYUV(byte[] yuv, int width, int height) {
        long start = System.currentTimeMillis();
        MultiFormatReader multiFormatReader = new MultiFormatReader();
        multiFormatReader.setHints(null);

        Result rawResult = null;
        PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(yuv, width, height, 0, 0,
                width, height, false);
        if (source != null) {
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            try {
                rawResult = multiFormatReader.decodeWithState(bitmap);
            } catch (ReaderException re) {
                re.printStackTrace();
            } finally {
                multiFormatReader.reset();
                multiFormatReader = null;
            }
        }
        long end = System.currentTimeMillis();
        LogUtils.d(TAG + " --barcode decode in " + (end - start) + " ms");
        return rawResult;
    }


    /**
     * RGB轉YUV的公式是:
     * Y=0.299R+0.587G+0.114B;
     * U=-0.147R-0.289G+0.436B;
     * V=0.615R-0.515G-0.1B;
     *
     * @param yuv
     * @param argb
     * @param width
     * @param height
     */
    private static void encodeYUV420SP(byte[] yuv, int[] argb, int width, int height) {
        // 幀圖片的畫素大小
        final int frameSize = width * height;
        // ---YUV資料---
        int Y, U, V;
        // Y的index從0開始
        int yIndex = 0;
        // UV的index從frameSize開始
        int uvIndex = frameSize;
        // ---顏色資料---
        int R, G, B;
        int rgbIndex = 0;
        // ---迴圈所有畫素點,RGB轉YUV---
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {
                R = (argb[rgbIndex] & 0xff0000) >> 16;
                G = (argb[rgbIndex] & 0xff00) >> 8;
                B = (argb[rgbIndex] & 0xff);
                //
                rgbIndex++;
                // well known RGB to YUV algorithm
                Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
                U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
                V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;
                Y = Math.max(0, Math.min(Y, 255));
                U = Math.max(0, Math.min(U, 255));
                V = Math.max(0, Math.min(V, 255));
                // NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2
                // meaning for every 4 Y pixels there are 1 V and 1 U. Note the sampling is every other
                // pixel AND every other scan line.
                // ---Y---
                yuv[yIndex++] = (byte) Y;
                // ---UV---
                if ((j % 2 == 0) && (i % 2 == 0)) {
                    //
                    yuv[uvIndex++] = (byte) V;
                    //
                    yuv[uvIndex++] = (byte) U;
                }
            }
        }
    }

注:對於YUV和RGB的理解,引用知乎上看到的資料

相關推薦

Android開源使用ZXing開源生成識別本地圖片

/** * 解析二維碼(使用解析RGB編碼資料的方式) * * @param path * @return */ public static Result decodeBarcodeRGB(String path) { if (Text

Android NDK開發引入第三方

在Android開發中我們經常要把一些比較看重安全或者計算效率的東西通過JNI呼叫C/C++程式碼來實現,如果需要實現的功能簡單或者你的C/C++程式碼能力比較強,但是目前還是有很多功能強大的第三方庫的,比如openssl、FFmpeg等,呼叫這些第三方實現顯然比重複造輪子實際的多。 本教程適合將原始的動態

Python數據數據基本操作

there 開發 uniq gin 忘記密碼 on() only 整數 開始 安裝(基於centos) yum -y install mariadb mariadb-server # centos7版本 yum -y install my

Android--四大元件BroadCastReceiver(生命週期、實現原理使用等)

####1. BroadCastReceiver是什麼? ####2. 廣播型別 ######1). 有序廣播 ######2). 無序廣播 ####3. 生命週期 ####4. 實現原理 ####5. 使用方法 ####6. 許可權問題(安全性) ####7. LocalBroad

Android學習筆記百度地圖(駕車路線搜尋RouteOverlay步行路線搜尋RouteOverlay)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

codecombat邊遠地區的森林1-11關地牢38關代分享

moved 是什麽 safe rac 1-1 mov 執行 左右 移動 codecombat中國遊戲網址:http://www.codecombat.cn/ 全部代碼為javascript代碼分享 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

java生成帶logo的前端顯示

package com.utils.generate_qrcode; import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.awt.image.BufferedImage; imp

Android 網路開源Retrofit

    當前的網路開源庫有許多,如volley,okhttp,retrofit等,這三個庫當前是比較火的,其中,okhttp和retrofit由square團隊開發。關於這三個庫的區別,請移步stackoverflow或者知乎檢視。開發過程中選擇什麼樣的開源庫需要更具

我的Android進階旅------>【強力推薦】Android開源圖表XCL-Charts版本釋出展示頁

         因為要做圖表相關的應用,後來百度發現了一個很好的Android開源圖表庫(XCL-Charts is a free charting library for Android plat

arcgis api for jsecharts開源js實現地圖統計圖分析

不能 rgba data ron 創建 apc att load reat 前面寫過一篇關於arcgis api for js實現地圖統計圖的,具體見:http://www.cnblogs.com/giserhome/p/6727593.html 那是基於dojo組件來實

zxing開源工作流程原始碼詳解

程式碼獲取 作為移動客戶端開發者來說,對二維碼識別或二維碼生成相關的開發需求肯定並不陌生,Android開發二維碼相關的功能通常都會使用或參考大名鼎鼎的zxing庫。而本文則主要是通過原始碼分析一下該開源庫掃描二維碼的工作流程,對這塊能有個更深的瞭解。 首先使用git將專案程式碼clone到本地,新建專案

開源EventBus使用詳解

簡介 EventBus是一種用於Android的釋出/訂閱事件匯流排。簡化了應用程式內各元件間、元件與後臺執行緒間的通訊。常用於Activity、Fragment和後臺Service之間通訊、傳

定製開源jar包和.so的引用

定製開源庫很多時候只是程式碼的開源,這次的要求是把jar包和.so檔案都放到庫裡,中間的過程還是有點曲折的。 首先我找到的是: 優雅的釋出Android開源庫(論JitPack的優越性) 本來我是按照這

zxing開源的基本使用

如果你的專案中有模組跟二維碼相關的話,那你一定聽過或者用過大名鼎鼎的zxing開源庫。 什麼是zxing? ZXing是一個開源的,用Java實現的多種格式的1D/2D條碼影象處理庫,它包含了聯絡到其他語言的埠。zxing可以實現使用手機的內建的攝像頭完成條形碼的掃描及解碼。 本篇文章就來學習zxing的基本

C++跨平臺開源

本篇文章主要介紹了”C++開源庫集合 “,主要涉及到C++開源庫集合 方面的內容,對於C++開源庫集合 感興趣的同學可以參考一下。 mimetic A free/GPL C++ MIME Library mimetic is a free/GPL Email library (MIME) w

C++跨平臺開源

值得學習的C/C++語言開源專案 (1)ACE 龐大、複雜,適合大型專案。開源、免費,不依賴第三方庫,支援跨平臺。 (2)Asio Asio基於Boost開發的非同步IO庫,封裝了Socket,簡化基於socket程式的開發。 開源、免費,支援跨平臺。 (3)POCO POCO C++ Libr

Android studio 引入第三方(github開源

現在github越來越火,也是個人的招牌了。很多很好的公開庫,都可以直接使用,可以使自己的app效果更加的炫,還可以縮短開發週期。 這裡就主要說下,如何匯入github上的專案,並如何引用。一開始匯入,會遇到挺多問題,也不知道咋處理,慢慢摸索了兩天,終於弄好了。 一、下載g

Android筆記--Android Studio 引用第三方開源類okhttp、gson時的打包混淆

在工程下找到proguard-rules.pro檔案下: -dontwarn #okhttp混淆配置 -keep class com.squareup.okhttp.** { *;} -dontw

Android如何快速尋找第三方開源在Jcenter上的最新版本

首先看一下問題: 問個問題 比如我想找最新的okhhtp compile的最新那句話 compile ‘com.squareup.okhttp:okhttp:2.4.0’ 2.4.0明顯不是最新的 應該怎麼找? 解決方法 先了解compile ‘com.squareup.okhttp:

Android 使用開源StickyGridHeaders來實現帶sections和headers的GridView顯示本地圖片效果

大家好!過完年回來到現在差不多一個月沒寫文章了,一是覺得不知道寫哪些方面的文章,沒有好的題材來寫,二是因為自己的一些私事給耽誤了,所以過完年的第一篇文章到現在才發表出來,2014年我還是會繼續在CSDN上面更新我的部落格,歡迎大家關注一下,今天這篇文章主要的是介紹下開源庫St