成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 代碼基于開源組件生成帶頭像的二維碼,推薦收藏!

開發(fā) 前端 開源
我們生成二維碼使用工具 zxing,合成圖片我們采用 thumbnailator,接下來我們實操一下吧。

二維碼在我們目前的生活工作中,隨處可見,日常開發(fā)中難免會遇到需要生成二維碼的場景,網(wǎng)上也有很多開源的平臺可以使用,不過這里我們可以通過幾個開源組件,自己來實現(xiàn)一下。

在動手之前我們先思考一下需要進行的操作,首先我們需要生成一個二維碼,其次我們需要在這里二維碼中間添加一個頭像。

這里我們生成二維碼使用工具 zxing,合成圖片我們采用 thumbnailator,接下來我們實操一下吧。

生成二維碼

首先我們先根據(jù)目標地址,生成一個二維碼,這里我們使用的是組件 zxing,在 SpringBoot 的pom依賴中,我們加入下面的依賴。

<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.0</version>
</dependency>

然后編寫工具類 QRCodeGenerator.java

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;


publicclass QRCodeGenerator {

/**
* 根據(jù)內(nèi)容,大小生成二維碼到指定路徑
*
* @param contents 跳轉(zhuǎn)的鏈接
* @param width 寬度
* @param height 高度
* @param filePath 路徑
* @throws WriterException
* @throws IOException
*/
public static void generateQrWithImage(String contents, int width, int height, String filePath) throws WriterException, IOException {
//構(gòu)造二維碼寫碼器
MultiFormatWriter mutiWriter = new com.google.zxing.MultiFormatWriter();
HashMap<EncodeHintType, Object> hint = new HashMap<>(16);
hint.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hint.put(EncodeHintType.ERROR_CORRECTION, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.H);
hint.put(EncodeHintType.MARGIN, 1);
//生成二維碼
BitMatrix bitMatrix = mutiWriter.encode(contents, BarcodeFormat.QR_CODE, width, height, hint);
Path path = FileSystems.getDefault().getPath(filePath);
MatrixToImageWriter.writeToPath(bitMatrix, "jpeg", path);
}
}

這個靜態(tài)方法有四個參數(shù),分別是:

  • 跳轉(zhuǎn)的鏈接內(nèi)容;
  • 二維碼的寬度;
  • 二維碼的高度;
  • 生成的二維碼后的存放路徑;

代碼中還有幾個常量,EncodeHintType.CHARACTER_SET:表示編碼;EncodeHintType.ERROR_CORRECTION 表示二維碼的容錯率;EncodeHintType.MARGIN 表示二維碼的邊框。

解釋一下什么是二維碼的容錯率,大家在日常生活或者工作中應該會發(fā)現(xiàn),有些二維碼輕輕一掃就掃成功了,有的二維碼卻很難掃成功,這背后就是二維碼的容錯率的原因(對,有時候并不是你的網(wǎng)絡問題!)。

不同密度的二維碼所包含的信息其編碼的字符、容錯率均不同。密度越低,編碼的字符個數(shù)越少、容錯率越低,二維碼容錯率表示二維碼圖標被遮擋多少后,仍可以被掃描出來的能力。目前,典型的二維碼的容錯率分為 7%、15%、25%、30% 四個等級,容錯率越高,越容易被快速掃描。“但是,容錯率越高,二維碼里面的黑白格子也就越多。因此,對于目前主流手機,在絕大多數(shù)掃描場景下,仍普遍應用 7% 容錯率的二維碼就能滿足需求。

感興趣的小伙伴也可以自己嘗試幾個不同的容錯率,看看掃碼的難度有沒有變化。

接下來,我們編寫一個 main 方法來生成一個二維碼

public static void main(String[] args) {
try {
QRCodeGenerator.generateQrWithImage("https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzkzODE3OTI0Ng==&scene=124#wechat_redirect", 500, 500, "./QRCode.jpeg");
} catch (Exception e) {
}
}

運行完上面的 main 方法,我們可以得到一個二維碼,到這里我們第一步已經(jīng)完成了,接下來就是給這個二維碼加上我們的頭像。

添加頭像

添加頭像我們需要準備一個頭像的照片,阿粉這里就用阿粉的頭像了,如果這里有現(xiàn)成大小的頭像就直接拿來使用就行,如果沒有也沒有關(guān)系,我們可以自己裁剪,這里我們就需要用來圖片處理工具 thumbnailator 了。

阿粉

先將頭像處理成 100 x 100 的大小,然后再合成上去就行,代碼如下:

public static void main(String[] args) {
try {
// 將大圖片縮小到指定大小
// ThumbnailsImageUtils.size("./阿粉.jpeg", 100, 100, 1, "./阿粉100.png");
// 通過水印的形式,將頭像加到生成的二維碼上面
ThumbnailsImageUtils.watermark("./QRCode.jpeg",
500, 500, Positions.CENTER, "./阿粉100.png",
1f, 1f, "./result.png");
} catch (Exception e) {
}
}

這個就是最終生成的帶頭像的二維碼啦,友情提示,掃碼可以看到更多優(yōu)質(zhì)文章。

通過上面的代碼可以看到,ThumbnailsImageUtils 是真的很多強大,一行代碼就能搞定圖片縮小和圖片合成,更多關(guān)于 ThumbnailsImageUtils 工具類的完整代碼如下,趕緊收藏起來。


import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
* <br>
* <b>功能:</b><br>
* <b>作者:</b>@author ziyou<br>
* <b>日期:</b>2018-05-25 16:17<br>
* <b>詳細說明:</b>使用google開源工具Thumbnailator實現(xiàn)圖片的一系列處理<br>
*/
publicclass ThumbnailsImageUtils {

privatefinalstatic Logger logger = LoggerFactory.getLogger(ThumbnailsImageUtils.class);

/**
* 將原圖根據(jù)指定大小生產(chǎn)新圖
*
* @param sourceFilePath 原始圖片路徑
* @param width 指定圖片寬度
* @param height 指定圖片高度
* @param targetFilePath 目標圖片路徑
* @return 目標圖片路徑
* @throws IOException
*/
public static String thumb(String sourceFilePath, Integer width, Integer height, String targetFilePath) throws IOException {
Thumbnails.of(sourceFilePath)
.forceSize(width, height)
.toFile(targetFilePath);
return targetFilePath;
}


/**
* 按照比例進行縮放
*
* @param sourceFilePath 原始圖片路徑
* @param scale scale(比例)
* @param targetFilePath 目標圖片路徑
* @return 目標圖片路徑
* @throws IOException
*/
public static String scale(String sourceFilePath, Double scale, String targetFilePath) throws IOException {
Thumbnails.of(sourceFilePath)
.scale(scale)
.toFile(targetFilePath);
return targetFilePath;
}


/**
* 不按照比例,指定大小進行縮放
*
* @param sourceFilePath 原始圖片路徑
* @param width 指定圖片寬度
* @param height 指定圖片高度
* @param targetFilePath 目標圖片路徑
* keepAspectRatio(false) 默認是按照比例縮放的
* @return 目標圖片路徑
* @throws IOException
*/
public static String size(String sourceFilePath, Integer width, Integer height, float quality, String targetFilePath) throws IOException {
Thumbnails.of(sourceFilePath)
.size(width, height)
.outputQuality(quality)
.keepAspectRatio(false)
.toFile(targetFilePath);
return targetFilePath;
}


/**
* 指定大小和角度旋轉(zhuǎn)
*
* @param sourceFilePath 原始圖片路徑
* @param width 指定圖片寬度
* @param height 指定圖片高度
* @param rotate rotate(角度),正數(shù):順時針 負數(shù):逆時針
* @param targetFilePath 目標圖片路徑
* @return 目標圖片路徑
* @throws IOException
*/
public static String rotate(String sourceFilePath, Integer width, Integer height, Double rotate, String targetFilePath) throws IOException {
Thumbnails.of(sourceFilePath)
.size(width, height)
.rotate(rotate)
.toFile(targetFilePath);
return targetFilePath;
}


/**
* 指定角度旋轉(zhuǎn)
*
* @param sourceFilePath 原始圖片路徑
* @param rotate rotate(角度),正數(shù):順時針 負數(shù):逆時針
* @param targetFilePath 目標圖片路徑
* @return 目標圖片路徑
* @throws IOException
*/
public static String rotate(String sourceFilePath, Double rotate, String targetFilePath) throws IOException {
Thumbnails.of(sourceFilePath)
.rotate(rotate)
.toFile(targetFilePath);
return targetFilePath;
}


/**
* @param sourceFilePath 原始圖片路徑
* @param width 指定圖片寬度
* @param height 指定圖片高度
* @param position 水印位置
* @param waterFile 水印文件
* @param opacity 水印透明度
* @param quality 輸出文件的質(zhì)量
* @param targetFilePath 目標圖片路徑
* @return 目標圖片路徑
* @throws IOException
*/
public static String watermark(String sourceFilePath, Integer width, Integer height, Positions position, String waterFile, float opacity, float quality, String targetFilePath) throws IOException {
Thumbnails.of(sourceFilePath)
.size(width, height)
.watermark(position, ImageIO.read(new File(waterFile)), opacity)
.outputQuality(quality)
.toFile(targetFilePath);
return targetFilePath;
}


public static BufferedImage watermarkList(BufferedImage buffImg, int length, File[] waterFileArray) throws IOException {
int x = 0;
int y = 0;
if (buffImg == null) {
// 獲取底圖
buffImg = new BufferedImage(1200, 1200, BufferedImage.SCALE_SMOOTH);
} else {
x = (length % 30) * 40;
y = (length / 30) * 40;
}
// 創(chuàng)建Graphics2D對象,用在底圖對象上繪圖
Graphics2D g2d = buffImg.createGraphics();
// 將圖像填充為白色
g2d.setColor(Color.WHITE);
g2d.fillRect(x, y, 1200, 40 * (waterFileArray.length + length));
for (int i = 0; i < waterFileArray.length; i++) {
// 獲取層圖
BufferedImage waterImg = ImageIO.read(waterFileArray[i]);
// 獲取層圖的寬度
int waterImgWidth = waterImg.getWidth();
// 獲取層圖的高度
int waterImgHeight = waterImg.getHeight();
// 在圖形和圖像中實現(xiàn)混合和透明效果
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));
// 繪制
Integer j = i / 30;
Integer index = i - j * 30;
g2d.drawImage(waterImg, waterImgWidth * index + 1, waterImgHeight * j, waterImgWidth, waterImgHeight, null);

}

// 釋放圖形上下文使用的系統(tǒng)資源
g2d.dispose();
return buffImg;
}

/**
* @param sourceFilePath 原始圖片路徑
* @param waterFile 水印文件
* @param targetFilePath 目標圖片路徑
* 透明度默認值0.5f,質(zhì)量默認0.8f
* @return 目標圖片路徑
* @throws IOException
*/
public static String watermark(String sourceFilePath, String waterFile, String targetFilePath) throws IOException {
Image image = ImageIO.read(new File(waterFile));
Integer width = image.getWidth(null);
Integer height = image.getHeight(null);
return watermark(sourceFilePath, width, height,
Positions.BOTTOM_RIGHT, waterFile, 0.5f, 0.8f, targetFilePath);
}


/**
* 將圖片轉(zhuǎn)化為指定大小和格式的圖片
*
* @param sourceFilePath
* @param width
* @param height
* @param format
* @param targetFilePath
* @return
* @throws IOException
*/
public static String changeFormat(String sourceFilePath, Integer width, Integer height, String format, String targetFilePath) throws IOException {
Thumbnails.of(sourceFilePath)
.size(width, height)
.outputQuality(0.8f)
.outputFormat(format)
.toFile(targetFilePath);
return targetFilePath;
}


/**
* 根據(jù)原大小轉(zhuǎn)化指定格式
*
* @param sourceFilePath
* @param format
* @param targetFilePath
* @return
* @throws IOException
*/
public static String changeFormat(String sourceFilePath, String format, String targetFilePath) throws IOException {
Image image = ImageIO.read(new File(sourceFilePath));
Integer width = image.getWidth(null);
Integer height = image.getHeight(null);
Thumbnails.of(sourceFilePath)
.size(width, height)
.outputFormat(format)
.toFile(targetFilePath);
return targetFilePath;
}

/**
* 輸出到輸出流
*
* @param sourceFilePath
* @param targetFilePath
* @return
* @throws IOException
*/
public static String toOutputStream(String sourceFilePath, String targetFilePath) throws IOException {
OutputStream os = new FileOutputStream(targetFilePath);
Thumbnails.of(sourceFilePath).toOutputStream(os);
return targetFilePath;
}


/**
* 輸出到BufferedImage
*
* @param sourceFilePath
* @param format
* @param targetFilePath
* @return
* @throws IOException
*/
public static String asBufferedImage(String sourceFilePath, String format, String targetFilePath) throws IOException {
/**
* asBufferedImage() 返回BufferedImage
*/
BufferedImage thumbnail = Thumbnails.of(sourceFilePath).size(1280, 1024).asBufferedImage();
ImageIO.write(thumbnail, format, new File(targetFilePath));
return targetFilePath;
}
}

總結(jié)

今天阿粉通過兩個組件帶大家實踐了一個二維碼的生成和圖片的合成,這兩個技巧在工作中難免會使用到,趕緊保存使用起來吧。

責任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2024-06-26 08:46:45

2021-02-08 08:40:00

Zint二維碼開源

2023-11-17 15:44:06

C++庫生成二維碼

2023-11-17 09:07:51

.NET生成二維碼識別二維碼

2015-09-24 09:56:19

.NET二維碼

2013-10-29 09:46:05

二維碼

2013-03-27 16:13:17

Android開發(fā)Android二維碼生QR生成

2020-12-30 10:55:01

代碼Java二維碼

2013-01-30 12:16:49

二維碼NFC近場通訊

2021-01-14 06:19:45

QRCanvas開源二維碼

2023-10-31 08:16:16

Go語言二維碼

2014-12-31 15:37:16

二維碼生成掃描

2020-08-07 14:18:03

二維碼Go語言編程

2017-11-21 09:00:15

PHP二維碼LOGO圖像

2012-04-01 09:53:13

二維碼

2017-02-21 09:17:46

二維碼漏洞

2011-12-06 16:40:45

二維碼快拍二維碼靈動快拍

2011-11-24 16:00:23

信息圖QR碼二維碼

2015-11-09 13:03:47

JavaServlet創(chuàng)建二維碼

2022-03-24 09:43:29

二維碼二維碼修改器github
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 91精品国产综合久久福利软件 | 在线国产视频 | 日韩视频一区在线观看 | 高清国产一区二区 | 欧美中文字幕在线观看 | 中文字幕精品一区二区三区精品 | 免费在线黄 | 在线日韩欧美 | 免费av一区二区三区 | 日本黄色免费片 | 亚洲欧美一区二区三区国产精品 | 国产欧美日韩 | 亚洲成人福利 | 国产高清久久久 | 国产精品一区二区免费 | 久久久久久精 | 欧美激情综合 | 91视频在线 | 在线国产一区 | 国产成人网 | 91久久国产综合久久 | 黑人粗黑大躁护士 | 一区二区三区欧美在线 | 亚洲成人播放器 | 欧美激情一区二区三区 | 精品久久久久久亚洲综合网 | 美女福利视频一区 | 玖玖视频 | 精品国产99 | 日韩亚洲欧美一区 | 在线国产一区二区 | 亚洲精品一 | 日韩国产中文字幕 | 久久99国产精品 | 欧美黄色一区 | 91日韩 | 亚洲成人福利在线观看 | 在线观看中文字幕 | 天天操天天干天天爽 | 男人天堂免费在线 | 国产一区二区中文字幕 |