版權聲明:歡迎轉載,請注明沉默王二原創。 https://blog.csdn.net/qing_gee/article/details/77341821
世界上25%的人都有拖延症——但我覺得這統計肯定少了,至少我就是一名拖延症患者。一直想把“Java生成名片式(帶有背景圖檔、使用者網絡頭像、使用者昵稱)的二維碼”這篇部落格分享出來,但一直拖啊拖,拖到現在,真應了蘇格蘭的那句諺語——“什麼時候都能做的事,往往什麼時候都不會去做。”
零、效果圖
- 左上角為微信頭像。
- 沉默王二是文字昵稱。
- 附帶URL為 http://blog.csdn.net/qing_gee 的二維碼
- 還有指定的背景圖。
使用場景:
點公衆号的微信菜單“我的二維碼”,然後展示一張名片式的二維碼給使用者。
一、源碼下載下傳
可以通過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);
如果你從GitHub上下載下傳到源碼後,可直接通過eclipse把工程導入到你的工作庫,運作/qrcode-utils/src/test/QrcodeUtilsTest.java 即可生成二維碼。
2.2 目錄檔案介紹
- 核心類為QrcodeUtils.java(用來生成二維碼)
- 名片式二維碼的參數類MatrixToBgImageConfig.java
- 測試用例QrcodeUtilsTest.java
- res資源包下有兩張圖檔,bg.jpg為指定的背景圖、default_headimg.jpg為預設的頭像圖
- /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);
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();
}
通過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;
}
}
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);
}
}
好了,源碼就先介紹到這喽。
你是那25%中的一個嗎?如果你想終結拖延症,那麼可以掃描下方二維碼關注我哦(好像這廣告語寫得不怎麼漂亮)。