欢迎访问个人博客:***德鲁大叔撸代码***
在平时的生活中,到处都存在着二维码 二维码其实就是一种编码技术,只是这种编码技术是用在图片上了,将给定的一些文字,数字转换为一张经过特定编码的图片,而解析二维码则相反,就是将一张经过编码的图片解析为数字或者文字。
今天就动手写一个二维码生成和解析的程序,实现功能:当输入二维码的内容为网址的话,扫描二维码的时候自动打开网址;当二维码的内容为文本时,扫描二维码显示具体文本信息。
源码地址:Java生成和解析二维码
作为一个程序员,必须要学会站在巨人的肩膀上进行开发,什么意思呢?当有一个需求你觉得是很常用的,也就是说是公共的,那么不用怀疑!!!无论你用什么方式,都可以在开源社区中找到很好的开源工具。那么,二维码技术已经是很普遍的了,接下来就是去找好的开源工具了。在这里呢,我使用的是谷歌的插件进行二维码的生成。
具体步骤如下
一、创建一个基础的SpringBoot项目
省略
二、引入依赖
<!--公共-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
<!--谷歌提供的二维码插件-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.3</version>
</dependency>
三、二维码生成工具类
1、基本常量
private static final String CHARSET = "UTF-8";
private static final int CODE_WIDTH = 360;
private static final int CODE_HEIGHT = 360;
//前景色 黑色
private static final int FRONT_COLOR = 0x000000;
//背景色 白色
private static final int BACKGROUND_COLOR = 0xFFFFFF;
2、生成二维码
/**
* 二维码生成方法
* @param codeContent 二维码内容
* @param imgSaveDir 本地保存地址
* @param fileNme 生成二维码的文件名
*/
public static void createQRCode(String codeContent, File imgSaveDir, String fileNme){
try{
if(StringUtils.isBlank(codeContent)){
log.info("二维码文本内容为空,不可生成二维码,请重试");
return;
}
if(imgSaveDir == null || imgSaveDir.isFile()){
imgSaveDir = FileSystemView.getFileSystemView().getHomeDirectory();
log.info("二维码存放地址默认存放路径在桌面");
}
if(!imgSaveDir.exists()){
imgSaveDir.mkdirs();
log.info("创建二维码存放的目录");
}
if(StringUtils.isBlank(fileNme)){
fileNme = System.currentTimeMillis() + ".jpg";
log.info("未传入二维码文件名,随机生成一个二维码文件名");
}
codeContent = codeContent.trim();
/**
* com.google.zxing.EncodeHintType:编码提示类型,枚举类型
* EncodeHintType.CHARACTER_SET:设置字符编码类型
* EncodeHintType.ERROR_CORRECTION:设置误差校正
* 不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的
* EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近
*/
Map<EncodeHintType, Object> hints = new HashMap();
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
hints.put(EncodeHintType.MARGIN, 1);
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
/**
* codeContent 二维码内容 如果是一个网页地址,如 https://www.kyriemtx.com/ 则 微信扫一扫会直接进入此地址
* BarcodeFormat.QR_CODE format:编码类型,如 条形码,二维码 等
* width: 二维码的宽度
* height:二维码的高度
* hints: 二维码内容的编码类型
*/
BitMatrix bitMatrix = multiFormatWriter.encode(codeContent, BarcodeFormat.QR_CODE,CODE_WIDTH,CODE_HEIGHT,hints);
BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH,CODE_HEIGHT,BufferedImage.TYPE_INT_RGB);
for(int x = 0;x<CODE_WIDTH;x++){
for(int y = 0;y<CODE_HEIGHT;y++){
bufferedImage.setRGB(x,y,bitMatrix.get(x,y) ? FRONT_COLOR:BACKGROUND_COLOR);
}
}
File codeImgFile = new File(imgSaveDir,fileNme);
ImageIO.write(bufferedImage,"jpg",codeImgFile);
log.info("二维码生成成功,文件名:{},存放路径:{}",fileNme,codeImgFile.getAbsolutePath());
}catch (Exception e){
log.info("生成二维码失败");
return;
}
}
3、验证二维码生成方法
public static void main(String[] args) throws Exception{
String code = "http://kyriemtx.com";
createQRCode(code,null,null);
}
运行结果:
扫描生成的二维码自动打开网址:
四、生成二维码显示在页面
1、首先引入模板引擎
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2、配置
server:
port: 8089
servlet:
context-path: /qrcode
spring:
thymeleaf:
prefix: classpath:/templates/
suffix: .html
servlet:
content-type: text/html
encoding: UTF-8
cache: false
mode: HTML5
3、编写页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>二维码生成器</title>
<script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<textarea placeholder="请输入二维码内容..........."></textarea><br>
<button>点击生成二维码</button><br><br><br>
<span class="hint"></span>
<div class="qrCodeDiv">
<img src="" th:src="@{/createQRCode}" id="codeImg">
</div>
</body>
<script type="text/javascript">
$(function () {
$("button").click(function () {
var codeContent = $("textarea").val();
console.log(codeContent);
if (codeContent.trim() == "") {
$(".hint").text("二维码内容不能为空").fadeIn(500);
} else {
$(".hint").text("").fadeOut(500);
$("#codeImg").attr("src", "/qrcode/createQRCode?codeContent=" + codeContent);
}
});
});
</script>
<style type="text/css">
textarea {
font-size: 16px;
width: 300px;
height: 100px;
}
.hint {
color: red;
display: none;
}
.qrCodeDiv {
width: 200px;
height: 200px;
border: 2px solid sandybrown;
}
.qrCodeDiv img {
max-height: 100%;
max-width: 100%;
}
</style>
</html>
4、controller类
@Controller
@Slf4j
public class QRController {
@GetMapping("/createQRCode")
public void getQRCode(String codeContent, HttpServletResponse response){
try {
QRCodeUtils.createCodeToOutputStream(codeContent,response.getOutputStream());
}catch (Exception e){
log.info("生成二维码失败");
}
}
@GetMapping("/index")
public ModelAndView index(ModelAndView modelAndView) {
modelAndView.setViewName("index");
return modelAndView;
}
}
5、编写输入把二位输出到页面的方法(最重要!!!!!)
public static void createCodeToOutputStream(String codeContext, OutputStream outputStream){
try {
if(StringUtils.isBlank(codeContext)){
log.info("二维码内容为空,生成一个随默认的二维码");
codeContext = "http://kyriemtx.com";
}
codeContext = codeContext.trim();
Map<EncodeHintType, Object> hints = new HashMap();
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
hints.put(EncodeHintType.MARGIN, 1);
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
BitMatrix bitMatrix = multiFormatWriter.encode(codeContext, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);
BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);
for (int x = 0; x < CODE_WIDTH; x++) {
for (int y = 0; y < CODE_HEIGHT; y++) {
bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR);
}
}
ImageIO.write(bufferedImage, "png", outputStream);
}catch (Exception e){
log.info("生成二维码失败");
}
}
五、解析二维码
所谓解析二维码其实就是传入需要解析的二维码的全路径,输出当前二维码的内容。具体方法如下:
/**
* 解析二维码
* @param filePath 二维码文件存放路径
* @return
* @throws Exception
*/
public static String parseQRCode(String filePath) throws Exception{
if(StringUtils.isBlank(filePath)){
log.info("二维码存放路径不能为空");
return null;
}
File codeFile = new File(filePath);
BufferedImage image;
image = ImageIO.read(codeFile);
if (image == null) {
return null;
}
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result;
Hashtable hints = new Hashtable();
hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
result = new MultiFormatReader().decode(bitmap, hints);
String resultStr = result.getText();
return resultStr;
}
测试得到的结果如下:
以上就是如何使用JAVA生成和解析二维码的简单实现方法。