1. 程式人生 > >Android 使用Zxing生成自定義二維碼

Android 使用Zxing生成自定義二維碼

最近有小夥伴問我,如何在Android端生成自己想要的二維碼,我看了下,大致上二維碼分為兩種,一種是純二維碼,一種是中間帶圖片的二維碼。下面我們看一下這兩種是如何實現的。

執行截圖

初始頁

輸入你想生成的連結或文字

再試試帶圖片的二維碼

生成後可以直接掃描,進入你填寫的連結頁面。

專案結構

可以看到非常之簡單,主要就是自己封裝了一個生成二維碼的工具類

下面我們看一下具體實現

首先引入Zxing依賴

 implementation 'com.google.zxing:core:3.2.1'

xml佈局檔案

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="100dp">

                <ImageView
                    android:id="@+id/img"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:src="@mipmap/ic_launcher"
                    />
        </LinearLayout>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:orientation="vertical">

                <EditText
                    android:id="@+id/txt"
                    android:layout_width="match_parent"
                    android:hint="請輸入你想生成的名字或連結"
                    android:gravity="center"
                    android:layout_height="wrap_content"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
                <Button
                    android:id="@+id/btn2"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:text="生成純二維碼"/>

                <Button
                    android:id="@+id/btn1"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:text="生成中間帶圖片二維碼"/>
        </LinearLayout>
        </LinearLayout>


</RelativeLayout>

生成二維碼

 public static Bitmap createQRImage(String content, int widthPix, int heightPix,
                                       Bitmap logoBm) {
        try {
//            if (content == null || "".equals(content)) {
//                return false;
//            }

            //配置引數
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            //容錯級別
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            //設定空白邊距的寬度
            hints.put(EncodeHintType.MARGIN, 1); //default is 4

            // 影象資料轉換,使用了矩陣轉換
            BitMatrix bitMatrix = null;
            try {
                bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
                        heightPix, hints);
            } catch (WriterException e) {
                e.printStackTrace();
            }
            int[] pixels = new int[widthPix * heightPix];
            // 下面這裡按照二維碼的演算法,逐個生成二維碼的圖片,
            // 兩個for迴圈是圖片橫列掃描的結果
            for (int y = 0; y < heightPix; y++) {
                for (int x = 0; x < widthPix; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * widthPix + x] = 0xff000000;
                    } else {
                        pixels[y * widthPix + x] = 0xffffffff;
                    }
                }
            }

            // 生成二維碼圖片的格式,使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);

            if (logoBm != null) {
                bitmap = addLogo(bitmap, logoBm);
            }

            //必須使用compress方法將bitmap儲存到檔案中再進行讀取。直接返回的bitmap是沒有任何壓縮的,
            // 記憶體消耗巨大!
            return bitmap;
//            return bitmap != null && bitmap.compress(Bitmap.CompressFormat.JPEG, 100);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

二維碼中間新增logo

/**
     * 在二維碼中間新增Logo圖案
     */
    private static Bitmap Logo(Bitmap src, Bitmap logo) {
        if (src == null) {
            return null;
        }

        if (logo == null) {
            return src;
        }

        //獲取圖片的寬高
        int srcWidth = src.getWidth();
        int srcHeight = src.getHeight();
        int logoWidth = logo.getWidth();
        int logoHeight = logo.getHeight();

        if (srcWidth == 0 || srcHeight == 0) {
            return null;
        }

        if (logoWidth == 0 || logoHeight == 0) {
            return src;
        }

        //logo大小為二維碼整體大小的1/5
        float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
        Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
        try {
            Canvas canvas = new Canvas(bitmap);
            canvas.drawBitmap(src, 0, 0, null);
            canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
            canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);

            canvas.save(Canvas.ALL_SAVE_FLAG);
            canvas.restore();
        } catch (Exception e) {
            bitmap = null;
            e.getStackTrace();
        }

        return bitmap;
    }

主activity直接呼叫

 //生成帶中間圖示的二維碼
                Bitmap success = ZxingUtils.createQRImage(txt.getText().toString().trim(), 100, 100,
                        BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
                img.setImageBitmap(success);

以上就是生成自定義二維碼的示例了,不當之處請多多指教。歡迎大家觀看我的部落格