zoukankan      html  css  js  c++  java
  • 2021.05.04 二维码生成与解析

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

    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>:就是一些配置信息,这里我只是配置了字符编码,其他配置信息可以去看下系统源码,mapkey只能是EncodeHintType的类型
    • onColoroffColor分别表示前景色和背景色,颜色值为16进制(Hex),可以根据自己的需要进行修改。

    其他的,都很简单,看下源码应该问题不大。

    生成效果

    效果还是很不错的,二维码的内容是

    name : 云中志
     content : hello qrCode
     date : 2021-05-04
     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
    

    本项目会每日更新,让我们一起学习,一起进步,遇见更好的自己,加油呀

  • 相关阅读:
    自动补全命令插件的安装(centos)
    vim tab设置为4个空格
    CentOS系统将UTC时间修改为CST时间
    Zabbix报错 zabbix:cannot convert value to numeric type解决
    php-fpm平滑重启开启关闭
    虚拟机启动network服务失败,Job for network.service failed because the control process exited with error code问题
    Tomcat中设置站点子目录的方法
    WordPress添加背景音乐plus教程
    WordPress使用必应每日一图作登录页面背景
    WordPress自定义美化
  • 原文地址:https://www.cnblogs.com/caoleiCoding/p/14730100.html
Copyright © 2011-2022 走看看