首页 文章详情

每日一例 | Java环境下,二维码的生成与解析

云中志 | 398 2021-05-09 20:25 0 0 0
UniSMS (合一短信)

提到二维码,想必大家都不会陌生,现如今它已经融入了我们生活的方方面面,从移动支付,到乘车码,再到健康码,现在连我们的电子社保卡、医保电子凭证也是基于二维码实现的,它的每一次应用都为我们的生活带来极大的便利性,可以说我们现在的生活越来越离不开它了,购物要扫码、看病就医购药要扫码、乘车要扫码,就连很多系统的登录也需要扫码,我们真的进入了有码时代……

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, 500500)
                :qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 500500, 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, 500500)
                :qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 500500, 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>:就是一些配置信息,这里我只是配置了字符编码,其他配置信息可以去看下系统源码,mapkey只能是EncodeHintType的类型
  • onColoroffColor分别表示前景色和背景色,颜色值为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 -


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter