• Java使用ZXing生成/解析二维码图片


    ZXing是一种开源的多格式1D/2D条形码图像处理库,在Java中的实现。重点是在手机上使用内置摄像头来扫描和解码设备上的条码,而不与服务器通信。然而,该项目也可以用于对桌面和服务器上的条形码进行编码和解码。目前支持这些格式:

    • UPC-A and UPC-E
    • EAN-8 and EAN-13
    • Code 39
    • Code 93
    • Code 128
    • ITF
    • Codabar
    • RSS-14 (all variants)
    • RSS Expanded (most variants)
    • QR Code
    • Data Matrix
    • Aztec ('beta' quality)
    • PDF 417 ('alpha' qua

    在这里仅使用它来生成/解析二维码:(解析二维码后续添加)

    创建maven项目,在pom.xml文件中添加zxing的jar包依赖:

        <!-- zxingQRcode生成支持包 -->
        <!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.3.3</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>

    以下为整合的二维码生成工具类:

    package com.esheng.util;
    
    import java.awt.AlphaComposite;
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    
    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.MatrixToImageConfig;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.CharacterSetECI;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    /**
     * QRCode生成工具类
     * @author: LinWenLi
     * @date: 2018-08-23 12:45:34
     */
    public class QRCodeUtils {
    
        
        /**
         * 二维码BufferedImage对象生成方法
         * @author LinWenLi
         * @date 2018-08-23 12:51:00
         * @param contents二维码内容
         * @param width二维码图片宽度
         * @param height二维码图片高度
         * @param margin二维码边框(0,2,4,8)
         * @throws Exception
         * @return: BufferedImage
         */
        public static BufferedImage createQRCode(String contents, int width, int height,int margin) throws Exception {
            if (contents == null || contents.equals("")) {
                throw new Exception("contents不能为空。");
            }
            // 二维码基本参数设置
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, CharacterSetECI.UTF8);// 设置编码字符集utf-8
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 设置纠错等级L/M/Q/H,当二维码被损毁一部分时,纠错等级越高,越可能读取成功;同样的,纠错等级越高,单位面积内点阵的点越多,机器扫描时,识别所需时间越长,当前设置等级为最高等级H
            hints.put(EncodeHintType.MARGIN, margin);// 可设置范围为0-10,但仅四个变化0 1(2) 3(4 5 6) 7(8 9 10)
            // 生成图片类型为QRCode
            BarcodeFormat format = BarcodeFormat.QR_CODE;
            // 创建位矩阵对象
            BitMatrix matrix = null;
            try {
                // 生成二维码对应的位矩阵对象
                matrix = new MultiFormatWriter().encode(contents, format, width, height, hints);
            } catch (WriterException e) {
                e.printStackTrace();
            }
            // 设置位矩阵转图片的参数
            MatrixToImageConfig config = new MatrixToImageConfig(Color.black.getRGB(), Color.white.getRGB());
            // 位矩阵对象转BufferedImage对象
            BufferedImage qrcode = MatrixToImageWriter.toBufferedImage(matrix, config);
            return qrcode;
        }
        
        /**
         * 二维码添加LOGO
         * @author LinWenLi
         * @date 2018-08-23 13:17:07
         * @param qrcode
         * @param width二维码图片宽度
         * @param height二维码图片高度
         * @param logoPath图标LOGO路径
         * @param logoSizeMultiple二维码与LOGO的大小比例
         * @throws Exception      
         * @return: BufferedImage      
         */
        public static BufferedImage createQRCodeWithLogo(BufferedImage qrcode,int width, int height, String logoPath, int logoSizeMultiple) throws Exception {
            File logoFile = new File(logoPath);
            if (!logoFile.exists() && !logoFile.isFile()) {
                throw new Exception("指定的LOGO图片路径不存在!");
            }
            try {
                // 读取LOGO
                BufferedImage logo = ImageIO.read(logoFile);
                // 设置LOGO宽高
                int logoHeight = qrcode.getHeight()/logoSizeMultiple;
                int logowidth = qrcode.getWidth()/logoSizeMultiple;
                // 设置放置LOGO的二维码图片起始位置
                int x = (qrcode.getWidth() - logowidth)/2;
                int y = (qrcode.getHeight() - logoHeight)/2;
                // 新建空画板
                BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                // 新建画笔
                Graphics2D g = (Graphics2D) combined.getGraphics();
                // 将二维码绘制到画板
                g.drawImage(qrcode, 0, 0, null);
                // 设置不透明度,完全不透明1f,可设置范围0.0f-1.0f
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
                // 绘制LOGO
                g.drawImage(logo, x, y, logowidth, logoHeight, null);
                return combined;
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        
        /**
         * 导出到指定路径
         * @author LinWenLi
         * @date 2018-08-23 12:59:03
         * @param bufferedImage
         * @param filePath图片保存路径
         * @param fileName图片文件名
         * @param formatName图片格式
         * @return: boolean      
         */
        public static boolean generateQRCodeToPath(BufferedImage bufferedImage,String filePath, String fileName, String formatName) {
            // 判断路径是否存在,不存在则创建
            File path = new File(filePath);
            if (!path.exists()) {
                path.mkdirs();
            }
            // 路径后补充斜杠
            if (filePath.lastIndexOf("\") != filePath.length() - 1) {
                filePath = filePath + "\";
            }
            // 组合为图片生成的全路径
            String fileFullPath = filePath + fileName + "." + formatName;
            boolean result = false;
            try {
                // 输出图片文件到指定位置
                result = ImageIO.write(bufferedImage, formatName, new File(fileFullPath));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }
    }

    然后是测试代码:

        public static void main(String[] args) {
            String contents = "二维码内容";
            int width = 220;// 二维码宽度
            int height = 220;// 二维码高度
            int margin = 0;// 二维码边距
            
            String logoPath = "C:\Users\myComputer\Desktop\LOGO.jpg";// LOGO图片路径
            int logoSizeMultiple = 3;// 二维码与LOGO的大小比例
            
            String filePath = "C:\Users\myComputer\Desktop\";// 指定生成图片文件的保存路径
            String fileName = "imageName";// 生成的图片文件名
            String formatName = "jpg";// 生成的图片格式,可自定义
    
            try {
                // 生成二维码
                BufferedImage qrcode = QRCodeUtils.createQRCode(contents, width, height,margin);
                // 添加LOGO
                qrcode = QRCodeUtils.createQRCodeWithLogo(qrcode, width, height, logoPath,logoSizeMultiple);
                // 导出到指定路径
                boolean result = QRCodeUtils.generateQRCodeToPath(qrcode, filePath, fileName, formatName);
                System.out.println("执行结果" + result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
  • 相关阅读:
    java线程池及创建多少线程合适
    消息队列消息积压了怎么办?
    Redis线程模型
    redis单线程如何支持高并发
    基于redis实现分布式锁
    PHP面试总结
    【转】Redis入门
    面试常考之二叉树
    计算机网络之面试常考
    操作系统之面试常考
  • 原文地址:https://www.cnblogs.com/new-life/p/9563202.html
Copyright © 2020-2023  润新知