java 實現二維碼生成工具類

二維碼工具篇

利用google的開源庫 zxing 來實現二維碼的生成,並實際修復一些常見的問題java

項目地址: http://git.oschina.net/liuyueyi/quicksilvergit

1. 設計思路

二維碼生成,採用如今用得比較多的開源框架 Zxingapi

既然都不是本身來生成二維碼了,爲何要作這個東西呢? 我要生成二維碼直接用官方的api不就好了,你這個不是化蛇添足麼!!!安全

- 官方的接入比較麻煩,特別是你想定製生成個性化的二維碼時,須要瞭解到zxing內部的一些設置參數,這個工具則下降了這些成本,與zxing打交道的配置都有它來作,對外暴露一些友好的,易懂的參數配置
- 實現對實際二維碼生成工具的解耦,假設zxing被爆出了什麼安全漏洞,這裏進行切換別的框架相對成本更低
- 個性化的定製 (如加logo)

目標app

- 最開始是但願設計個通用的,與具體的二維碼生成工具解耦(即做爲一個適配器層),實際上沒這麼玩...
- 制定對外暴露的配置項,用戶根據須要設置二維碼生成的參數,生成二維碼
    - 即對用戶而言,就兩部,設置參數, 生成二維碼, 總得交互就兩個接口

設計框架

- 設置參數採用builder模式, 生成配置項
- 一個適配層,將配置項適配爲zxing的二維碼生成參數
- 實際的處理層,生成二維碼
- 輸出層,能夠根據需求選擇輸出方式(輸出爲stream, 文件, bufferedImage)

2. 實現說明

  • 配置參數工具

    約定二維碼生成的參數以下測試

/**
    * The message to put into QrCode
    */
    private String msg;
    
    
    /**
    * qrcode center logo
    */
    private String logo;
    
    
    /**
    * qrcode image width
    */
    private Integer w;
    
    
    /**
    * qrcode image height
    */
    private Integer h;
    
    
    /**
    * qrcode bgcolor, default white
    */
    private Integer offColor;
    
    
    /**
    * qrcode msg color, default black
    */
    private Integer onColor;
    
    
    /**
    * qrcode message's code, default UTF-8
    */
    private String code;
    
    
    /**
    * 0 - 4
    */
    private Integer padding;
    
    
    /**
    * error level, default H
    */
    private ErrorCorrectionLevel errorCorrection;
    
    
    /**
    * output qrcode image type, default png
    */
    private String picType;
    ```

- 二維碼生成

    生成二維碼核心代碼 
`QRCode code = Encoder.encode(qrCodeConfig.getMsg(), errorCorrectionLevel, qrCodeConfig.getHints());`

    生成的code中, 就包含了二維碼矩陣, 剩下的就是將矩陣渲染輸出的問題, 輸出沒什麼好說的,這裏指出一點原生的zxing生成二維碼的白邊可能特別大,本工具類內部作了兼容,[點我查看大白邊修復指南](https://my.oschina.net/u/566591/blog/872770)


```java
    /**
     * 對 zxing 的 QRCodeWriter 進行擴展, 解決白邊過多的問題
     * <p/>
     * 源碼參考 {@link com.google.zxing.qrcode.QRCodeWriter#encode(String, BarcodeFormat, int, int, Map)}
     */
    private static BitMatrix encode(QrCodeConfig qrCodeConfig) throws WriterException {
        ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
        int quietZone = 1;
        if (qrCodeConfig.getHints() != null) {
            if (qrCodeConfig.getHints().containsKey(EncodeHintType.ERROR_CORRECTION)) {
                errorCorrectionLevel = ErrorCorrectionLevel.valueOf(qrCodeConfig.getHints().get(EncodeHintType.ERROR_CORRECTION).toString());
            }
            if (qrCodeConfig.getHints().containsKey(EncodeHintType.MARGIN)) {
                quietZone = Integer.parseInt(qrCodeConfig.getHints().get(EncodeHintType.MARGIN).toString());
            }

            if (quietZone > QUIET_ZONE_SIZE) {
                quietZone = QUIET_ZONE_SIZE;
            } else if (quietZone < 0) {
                quietZone = 0;
            }
        }

        QRCode code = Encoder.encode(qrCodeConfig.getMsg(), errorCorrectionLevel, qrCodeConfig.getHints());
        return renderResult(code, qrCodeConfig.getW(), qrCodeConfig.getH(), quietZone);
    }
    ```

## 3. 使用說明

寫完了就要開始實際用,寫了個測試類,貼出以下

```java
/**
     * 測試二維碼
     */
    @Test
    public void testGenQrCode() {
        String msg = "create qrcode!!!";

        // 簡單的生成
        QrCodeConfig qrCodeConfig = QrCodeGenWrapper.createQrCodeConfig()
                .setMsg(msg)
                .build();

        try {
            boolean ans = QrCodeGenWrapper.asFile(qrCodeConfig, "qrcode/gen.png");
            System.out.println(ans);
        } catch (Exception e) {
            System.out.println("create qrcode error! e: " + e);
            Assert.assertTrue(false);
        }


        //生成紅色的二維碼 300x300, 無邊框
        try {
            boolean ans = QrCodeGenWrapper.createQrCodeConfig()
                    .setMsg(msg)
                    .setW(300)
                    .setOnColor(0xffff0000)
                    .setOffColor(0xffffffff)
                    .setPadding(0)
                    .asFile("qrcode/gen_300x300.png");
            System.out.println(ans);
        } catch (Exception e) {
            System.out.println("create qrcode error! e: " + e);
            Assert.assertTrue(false);
        }


        // 生成帶logo的二維碼
        try {
            String logo = "https://git.oschina.net/uploads/34/2334_liuyueyi.png";
            boolean ans = QrCodeGenWrapper.createQrCodeConfig()
                    .setMsg(msg)
                    .setW(300)
                    .setOnColor(0xffff0000)
                    .setOffColor(0xffffffff)
                    .setPadding(0)
                    .setLogo(logo)
                    .asFile("qrcode/gen_300x300_logo.png");
            System.out.println(ans);
        } catch (Exception e) {
            System.out.println("create qrcode error! e: " + e);
            Assert.assertTrue(false);
        }


        // 根據本地文件生成待logo的二維碼
        try {
            String logo = "qrcode/logo.png";
            boolean ans = QrCodeGenWrapper.createQrCodeConfig()
                    .setMsg(msg)
                    .setW(300)
                    .setOnColor(0xffff0000)
                    .setOffColor(0xffffffff)
                    .setPadding(0)
                    .setLogo(logo)
                    .asFile("qrcode/gen_300x300_logo_v2.png");
            System.out.println(ans);
        } catch (Exception e) {
            System.out.println("create qrcode error! e: " + e);
            Assert.assertTrue(false);
        }
    }

從上面能夠看出,實際用的時候有兩種方式,沒什麼特別的,看本身需求選擇使用 - 先生成配置項, 而後根據配置項生成二維碼 - 設置參數,而後直接調用build的生成二維碼方法ui

相關文章
相關標籤/搜索