每日一例 | Java环境下,二维码的生成与解析
提到二维码,想必大家都不会陌生,现如今它已经融入了我们生活的方方面面,从移动支付,到乘车码,再到健康码,现在连我们的电子社保卡、医保电子凭证也是基于二维码实现的,它的每一次应用都为我们的生活带来极大的便利性,可以说我们现在的生活越来越离不开它了,购物要扫码、看病就医购药要扫码、乘车要扫码,就连很多系统的登录也需要扫码,我们真的进入了有码时代……
1994年日本人原昌宏发明了二维码,因为其发明人主动放弃了申请专利,所以二维码不受知识产权保护,任何人都可以制作和使用它。虽然二维码诞生于日本,但得益于中国移动互联网的迅猛发展,它反而在中国市场上得到了最广泛的应用。
今天,我们就来看下,如何用java
生成和解析二维码。
添加依赖
这里我们用的是google
的一个开源库,第一个依赖是核心库,第二个是javase
的依赖库,主要是用于二维码的解析。如果只是生成二维码的话,只需要引入核心库即可。
<!-- 添加 google 提供的二维码依赖 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
生成二维码
这里直接上代码,很简单。
/**
* 生成二维码图片
*
* @param content 文本内容
* @param fileSaveFullPath 文件保存路径
* @throws Exception
*/
public static void generateQrCodeImage(String content,
String fileSaveFullPath) throws Exception {
generateQrCodeImage(content, fileSaveFullPath, null);
}
/**
*
* @param content
* @param fileSaveFullPath
* @param hints 参数配置
* @throws Exception
*/
public static void generateQrCodeImage(String content,
String fileSaveFullPath, Map<EncodeHintType,Object> hints) throws Exception {
BitMatrix bitMatrix = Objects.isNull(hints) ?
qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 500, 500)
:qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 500, 500, hints);
System.out.println(bitMatrix);
int onColor = 0xFFC02C38;
// 背景色 白色
int offColor = 0xFFFFFFFF;
// 原生生成图片
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? onColor : offColor);
}
}
// 生成二维码图片
ImageIO.write(image, "png", new File(fileSaveFullPath));
}
你如果还依赖了javase
的包的话,上面生成的生成方法会更简单:
/**
*
* @param content
* @param fileSaveFullPath
* @param hints 参数配置
* @throws Exception
*/
public static void generateQrCodeImage(String content,
String fileSaveFullPath, Map<EncodeHintType,Object> hints) throws Exception {
BitMatrix bitMatrix = Objects.isNull(hints) ?
qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 500, 500)
:qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 500, 500, hints);
System.out.println(bitMatrix);
Path path = new File(fileSaveFullPath).toPath();
// 前景色 玉红色
int onColor = 0xFF1661AB;
// 背景色 白色
int offColor = 0xFFFFFFFF;
MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(onColor, offColor); MatrixToImageWriter.writeToPath(bitMatrix, "png", path, matrixToImageConfig);
}
两个方法唯一的区别是,后一个方法依赖javase
,在javase
的包中提供了MatrixToImageWriter.writeToPath()
方法,可以直接把生成的矩阵(BitMatrix
)转成图片;而第一个方法,参考了这个方法内容,所以显得更长,但是省掉了一个包(在大型企业项目中为避免包冲突,尽可能少加依赖)。
注意事项
这里有几点需要说明下:
encode
:需要指定二维码的宽和高,这里我给的500
(单位都是像素),可以根据需要调整Map<EncodeHintType,Object>
:就是一些配置信息,这里我只是配置了字符编码,其他配置信息可以去看下系统源码,map
的key
只能是EncodeHintType
的类型onColor
和offColor
分别表示前景色和背景色,颜色值为16
进制(Hex
),可以根据自己的需要进行修改。
其他的,都很简单,看下源码应该问题不大。
生成效果
效果还是很不错的,二维码的内容是
name : 云中志\n content : hello qrCode\n date : 2021-05-04\n url : https://www.cnblogs.com/caoleiCoding/
扫码效果
扫码之后就显示内容了
解析二维码
前面我们说了,解析要依赖javase
的包,其他的就没啥了,比生成更简单。
public static void readQrCodeImage() throws Exception {
Properties properties = System.getProperties();
properties.list(System.out);
FileInputStream fileInputStream = new FileInputStream("d://testQrCode1.png");
BufferedImage readImage = ImageIO.read(fileInputStream);
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(readImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result decode = qrCodeReader.decode(bitmap);
System.out.println(decode);
}
解析结果和我们刚才扫码结果一样:
我这里报错是因为生成图片的工具类(javase
依赖的一个第三方包)获取JDK
版本号报错了,我是open jDk9
,版本号是9
,但是包里面的,必须得是1.x
才能被截取,这个错我也改不了,也懒得更换JDK
版本,下面是包里面的源码:
各位小伙伴在写代码的时候,一定要尽可能规范,避免出现这种潜在的运行时错误,提取字符串后、数值转换前一定要有逻辑判断。
总结
今天讲了两个应用比较广泛的场景——生成二维码和解析二维码,掌握了这两个技术实现,简单的扫码登录,你应该可以简单实现了,说一个我的实现思路,可以在移动端调用相机拍照(h5
调用很简单,哪天试一下),前端可以直接解析二维码并进行相关业务操作,也可以把图片传给后端解析,然后进相关相关业务,验证通过后,将移动端的access_token
复制一份返回给web
端,扫码登录就实现了。好了,今天的Example
就到这里吧。
项目路径:
https://github.com/Syske/example-everyday
本项目会每日更新,让我们一起学习,一起进步,遇见更好的自己,加油呀
- END -