Android動態生成二維碼

圖片


什麼是二維碼


二維碼又稱二維條碼,常見的二維碼爲QR Code,QR全稱Quick Response,是一個近幾年來移動設備上超流行的一種編碼方式,它比傳統的Bar Code條形碼能存更多的信息,也能表示更多的數據類型。


動態生成二維碼方案


在查找二維碼生成方案時,發現很多方案的源頭都指向了GitHub的開源庫https://github.com/zxing/zxing


1. ZXing簡介:

ZXing全稱zebra crossing,翻譯過來就是『斑馬線』的意思。ZXing是一個採用Java實現的、開源的、支持多格式(一維/二維)的條形碼圖像處理庫。

其中,QRCode格式就是我們常說的二維碼格式。

注:QRCode(Quick Response Code:快速響應碼)是二維條形碼中最常用的一種格式,所以很多人直接將QRCode翻譯爲二維碼,而且連百度百科都這樣稱呼,筆者也暫時就這麼稱呼了。


2. ZXing庫引入

對於開發者來講,我們需要下載ZXing庫的一個jar包(core-x.x.x.jar)或者通過添加依賴的方式引入庫文件,具體方法如下:

方法一:ZXing提供了Maven庫,讓我們可以根據自己的需要選擇想要的jar包版本進行下載。Maven庫:https://repo1.maven.org/maven2/com/google/zxing/core/

方法二(推薦):對於使用AndroidStudio開發的程序員而言,可能更習慣於在.gradle文件中添加依賴。具體代碼如下(3.3.0是筆者使用時的最新版本,想知道最新版本是多少可以去Maven庫查):

dependencies {
   compile 'com.google.zxing:core:3.3.0'
}


3. ZXing庫的封裝


/**
* @ClassName: QRCodeUtil
* @Description: 二維碼工具類
* @Author Wangnan
* @Date 2017/2/10
*/





public class QRCodeUtil {
   /**
    * 創建二維碼位圖
    *
    * @param content 字符串內容
    * @param size 位圖寬&高(單位:px)
    * @return
    */






   @Nullable
   public static Bitmap createQRCodeBitmap(@Nullable String content, int size){
       return createQRCodeBitmap(content, size, "UTF-8", "H", "4", Color.BLACK, Color.WHITE, null, null, 0F);
   }
   /**
    * 創建二維碼位圖 (自定義黑、白色塊顏色)
    *
    * @param content 字符串內容
    * @param size 位圖寬&高(單位:px)
    * @param color_black 黑色色塊的自定義顏色值
    * @param color_white 白色色塊的自定義顏色值
    * @return
    */








   @Nullable
   public static Bitmap createQRCodeBitmap(@Nullable String content, int size, @ColorInt int color_black, @ColorInt int color_white){
       return createQRCodeBitmap(content, size, "UTF-8", "H", "4", color_black, color_white, null, null, 0F);
   }
   /**
    * 創建二維碼位圖 (帶Logo小圖片)
    *
    * @param content 字符串內容
    * @param size 位圖寬&高(單位:px)
    * @param logoBitmap logo圖片
    * @param logoPercent logo小圖片在二維碼圖片中的佔比大小,範圍[0F,1F]。超出範圍->默認使用0.2F
    * @return
    */








   @Nullable
   public static Bitmap createQRCodeBitmap(String content, int size, @Nullable Bitmap logoBitmap, float logoPercent){
       return createQRCodeBitmap(content, size, "UTF-8", "H", "4", Color.BLACK, Color.WHITE, null, logoBitmap, logoPercent);
   }
   /**
    * 創建二維碼位圖 (Bitmap顏色代替黑色) 注意!!!注意!!!注意!!! 選用的Bitmap圖片一定不能有白色色塊,否則會識別不出來!!!
    *
    * @param content 字符串內容
    * @param size 位圖寬&高(單位:px)
    * @param targetBitmap 目標圖片 (如果targetBitmap != null, 黑色色塊將會被該圖片像素色值替代)
    * @return
    */







   @Nullable
   public static Bitmap createQRCodeBitmap(String content, int size, Bitmap targetBitmap){
       return createQRCodeBitmap(content, size, "UTF-8", "H", "4", Color.BLACK, Color.WHITE, targetBitmap, null, 0F);
   }
   /**
    * 創建二維碼位圖 (支持自定義配置和自定義樣式)
    *
    * @param content 字符串內容
    * @param size 位圖寬&高(單位:px)
    * @param character_set 字符集/字符轉碼格式 (支持格式:{@link CharacterSetECI })。傳null時,zxing源碼默認使用 "ISO-8859-1"
    * @param error_correction 容錯級別 (支持級別:{@link ErrorCorrectionLevel })。傳null時,zxing源碼默認使用 "L"
    * @param margin 空白邊距 (可修改,要求:整型且>=0), 傳null時,zxing源碼默認使用"4"。
    * @param color_black 黑色色塊的自定義顏色值
    * @param color_white 白色色塊的自定義顏色值
    * @param targetBitmap 目標圖片 (如果targetBitmap != null, 黑色色塊將會被該圖片像素色值替代)
    * @param logoBitmap logo小圖片
    * @param logoPercent logo小圖片在二維碼圖片中的佔比大小,範圍[0F,1F],超出範圍->默認使用0.2F。
    * @return
    */














   @Nullable
   public static Bitmap createQRCodeBitmap(@Nullable String content, int size,
                                           @Nullable String character_set, @Nullable String error_correction, @Nullable String margin,
                                           @ColorInt int color_black, @ColorInt int color_white, @Nullable Bitmap targetBitmap,
                                           @Nullable Bitmap logoBitmap, float logoPercent)


{
       /** 1.參數合法性判斷 */
       if(TextUtils.isEmpty(content)){ // 字符串內容判空
           return null;
       }
       if(size <= 0){ // 寬&高都需要>0
           return null;
       }
       try {
           /** 2.設置二維碼相關配置,生成BitMatrix(位矩陣)對象 */
           Hashtable<EncodeHintType, String> hints = new Hashtable<>();
           if(!TextUtils.isEmpty(character_set)) {
               hints.put(EncodeHintType.CHARACTER_SET, character_set); // 字符轉碼格式設置
           }
           if(!TextUtils.isEmpty(error_correction)){
               hints.put(EncodeHintType.ERROR_CORRECTION, error_correction); // 容錯級別設置
           }
           if(!TextUtils.isEmpty(margin)){
               hints.put(EncodeHintType.MARGIN, margin); // 空白邊距設置
           }
           BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
           /** 3.根據BitMatrix(位矩陣)對象爲數組元素賦顏色值 */
           if(targetBitmap != null){
               targetBitmap = Bitmap.createScaledBitmap(targetBitmap, size, size, false);
           }
           int[] pixels = new int[size * size];
           for(int y = 0; y < size; y++){
               for(int x = 0; x < size; x++){
                   if(bitMatrix.get(x, y)){ // 黑色色塊像素設置
                       if(targetBitmap != null) {
                           pixels[y * size + x] = targetBitmap.getPixel(x, y);
                       } else {
                           pixels[y * size + x] = color_black;
                       }
                   } else { // 白色色塊像素設置
                       pixels[y * size + x] = color_white;
                   }
               }
           }
           /** 4.創建Bitmap對象,根據像素數組設置Bitmap每個像素點的顏色值,之後返回Bitmap對象 */
           Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
           bitmap.setPixels(pixels, 0, size, 0, 0, size, size);
           /** 5.爲二維碼添加logo小圖標 */
           if(logoBitmap != null){
               return addLogo(bitmap, logoBitmap, logoPercent);
           }
           return bitmap;
       } catch (WriterException e) {
           e.printStackTrace();
       }
       return null;
   }
   /**
    * 向一張圖片中間添加logo小圖片(圖片合成)
    *
    * @param srcBitmap 原圖片
    * @param logoBitmap logo圖片
    * @param logoPercent 百分比 (用於調整logo圖片在原圖片中的顯示大小, 取值範圍[0,1], 傳值不合法時使用0.2F)
    *                    原圖片是二維碼時,建議使用0.2F,百分比過大可能導致二維碼掃描失敗。
    * @return
    */








   @Nullable
   private static Bitmap addLogo(@Nullable Bitmap srcBitmap, @Nullable Bitmap logoBitmap, float logoPercent){
       /** 1. 參數合法性判斷 */
       if(srcBitmap == null){
           return null;
       }
       if(logoBitmap == null){
           return srcBitmap;
       }
       if(logoPercent < 0F || logoPercent > 1F){
           logoPercent = 0.2F;
       }
       /** 2. 獲取原圖片和Logo圖片各自的寬、高值 */
       int srcWidth = srcBitmap.getWidth();
       int srcHeight = srcBitmap.getHeight();
       int logoWidth = logoBitmap.getWidth();
       int logoHeight = logoBitmap.getHeight();
       /** 3. 計算畫布縮放的寬高比 */
       float scaleWidth = srcWidth * logoPercent / logoWidth;
       float scaleHeight = srcHeight * logoPercent / logoHeight;
       /** 4. 使用Canvas繪製,合成圖片 */
       Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
       Canvas canvas = new Canvas(bitmap);
       canvas.drawBitmap(srcBitmap, 0, 0, null);
       canvas.scale(scaleWidth, scaleHeight, srcWidth/2, srcHeight/2);
       canvas.drawBitmap(logoBitmap, srcWidth/2 - logoWidth/2, srcHeight/2 - logoHeight/2, null);
       return bitmap;
   }
}










































































































4.動態生成二維碼


Bitmap bitmap = QRCodeUtils.createQRCodeBitmap(qrUrl, 500);


5. 效果

圖片


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章