1. 程式人生 > >Java生成名片式的二維碼源碼分享

Java生成名片式的二維碼源碼分享

on() get close exception ase detail dispose 定義 closeable

世界上25%的人都有拖延癥——但我覺得這統計肯定少了,至少我就是一名拖延癥患者。一直想把“Java生成名片式(帶有背景圖片、用戶網絡頭像、用戶昵稱)的二維碼”這篇博客分享出來,但一直拖啊拖,拖到現在,真應了蘇格蘭的那句諺語——“什麽時候都能做的事,往往什麽時候都不會去做。”

零、效果圖

技術分享

  1. 左上角為微信頭像。
  2. 沈默王二是文字昵稱。
  3. 附帶URL為http://blog.csdn.net/qing_gee的二維碼
  4. 還有指定的背景圖。

使用場景:

點公眾號的微信菜單“我的二維碼”,然後展示一張名片式的二維碼給用戶。

一、源碼下載

可以通過GitHub直接下載https://github.com/qinggee/qrcode-utils.

二、源碼介紹

你肯定在網絡上見到過不少Java生成帶有logo的二維碼的源碼,這些都是生成二維碼的初級應用。相對來說,生成“名片式(帶有背景圖片、用戶網絡頭像、用戶名稱的二維碼圖片)的二維碼”可能更高級一點,但內在的原理其實是相似的——在一張指定的圖片對象Graphics2D利用drawImage()方法繪制上層圖像,利用drawString繪制文字。

2.1 使用接口

文件位置: /qrcode-utils/src/test/QrcodeUtilsTest.java

MatrixToBgImageConfig config = new MatrixToBgImageConfig();

// 網絡頭像地址       config.setHeadimgUrl("https://avatars2.githubusercontent.com/u/6011374?v=4&u=7672049c1213f7663b79583d727e95ee739010ec&s=400");

// 二維碼地址,掃描二維碼跳轉的地址
config.setQrcode_url("http://blog.csdn.net/qing_gee");

// 二維碼名片上的名字
config.setRealname("沈默王二");

// 通過QrcodeUtils.createQrcode()生成二維碼的字節碼
byte[] bytes = QrcodeUtils.createQrcode(config);
// 二維碼生成路徑
Path path = Files.createTempFile("qrcode_with_bg_", ".jpg");
// 寫入到文件
Files.write(path, bytes);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

如果你從GitHub上下載到源碼後,可直接通過eclipse把工程導入到你的工作庫,運行/qrcode-utils/src/test/QrcodeUtilsTest.java 即可生成二維碼。

技術分享

2.2 目錄文件介紹

技術分享

  1. 核心類為QrcodeUtils.java(用來生成二維碼)
  2. 名片式二維碼的參數類MatrixToBgImageConfig.java
  3. 測試用例QrcodeUtilsTest.java
  4. res資源包下有兩張圖片,bg.jpg為指定的背景圖、default_headimg.jpg為默認的頭像圖
  5. /qrcode-utils/lib為所需的jar包

2.3 QrcodeUtils.java

2.3.1 獲取背景

註意以下代碼中的第一行代碼。

InputStream inputStream = Thread.currentThread().getContextClassLoader()
                    .getResourceAsStream(config.getBgFile());
File bgFile = Files.createTempFile("bg_", ".jpg").toFile();
FileUtils.copyInputStreamToFile(inputStream, bgFile);
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2.3.2 獲取微信頭像

通過建立HttpGet請求來獲取微信頭像。

CloseableHttpClient httpclient = HttpClientBuilder.create().build();
HttpGet httpget = new HttpGet(config.getHeadimgUrl());
httpget.addHeader("Content-Type", "text/html;charset=UTF-8");
// 配置請求的超時設置
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(500)
        .setConnectTimeout(500).setSocketTimeout(500).build();
httpget.setConfig(requestConfig);

try (CloseableHttpResponse response = httpclient.execute(httpget);
        InputStream headimgStream = handleResponse(response);) {

    Header[] contentTypeHeader = response.getHeaders("Content-Type");
    if (contentTypeHeader != null && contentTypeHeader.length > 0) {
        if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) {

            // application/json; encoding=utf-8 下載媒體文件出錯
            String responseContent = handleUTF8Response(response);

            logger.warn("下載網絡頭像出錯{}", responseContent);
        }
    }

    headimgFile = createTmpFile(headimgStream, "headimg_" + UUID.randomUUID(), "jpg");
} catch (Exception e) {
    logger.error(e.getMessage(), e);
    throw new Exception("頭像文件讀取有誤!", e);
} finally {
    httpget.releaseConnection();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

通過createTmpFile方法將圖像下載到本地。

public static File createTmpFile(InputStream inputStream, String name, String ext) throws IOException {
        File tmpFile = File.createTempFile(name, ‘.‘ + ext);

        tmpFile.deleteOnExit();

        try (FileOutputStream fos = new FileOutputStream(tmpFile)) {
            int read = 0;
            byte[] bytes = new byte[1024 * 100];
            while ((read = inputStream.read(bytes)) != -1) {
                fos.write(bytes, 0, read);
            }

            fos.flush();
            return tmpFile;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.3.3 在背景圖上繪制二維碼、頭像、昵稱

private static void increasingImage(BufferedImage image, String format, String imagePath, File bgFile,
        MatrixToBgImageConfig config, File headimgFile) throws Exception {
    try {
        BufferedImage bg = ImageIO.read(bgFile);

        Graphics2D g = bg.createGraphics();

        // 二維碼的高度和寬度如何定義
        int width = config.getQrcode_height();
        int height = config.getQrcode_height();

        // logo起始位置,此目的是為logo居中顯示
        int x = config.getQrcode_x();
        int y = config.getQrcode_y();
        // 繪制圖
        g.drawImage(image, x, y, width, height, null);

        BufferedImage headimg = ImageIO.read(headimgFile);

        int headimg_width = config.getHeadimg_height();
        int headimg_height = config.getHeadimg_height();

        int headimg_x = config.getHeadimg_x();
        int headimg_y = config.getHeadimg_y();

        // 繪制頭像
        g.drawImage(headimg, headimg_x, headimg_y, headimg_width, headimg_height, null);

        // 繪制文字
        g.setColor(Color.GRAY);// 文字顏色
        Font font = new Font("宋體", Font.BOLD, 28);
        g.setFont(font);

        g.drawString(config.getRealname(), config.getRealname_x(), config.getRealname_y());

        g.dispose();
        // 寫入二維碼到bg圖片
        ImageIO.write(bg, format, new File(imagePath));
    } catch (Exception e) {
        throw new Exception("二維碼添加bg時發生異常!", e);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

好了,源碼就先介紹到這嘍。

http://blog.csdn.net/qing_gee/article/details/77341821

Java生成名片式的二維碼源碼分享