用java代码生成二维码工具类

本文介绍如何使用Java代码创建一个二维码生成工具类,详细解析关键步骤和代码实现,帮助开发者快速集成二维码生成功能。
摘要由CSDN通过智能技术生成

用java代码生成二维码工具类

package com.quectel.automation.util;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.CharacterSetECI;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.quectel.common.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;

public class QRCodeUtils {

    /**
     * 保存二维码图片到指定的路径
     *
     * @param content 二维码的内存(字符串)
     */
    public static String createQRCode(String content) {
        int width = 300;            //图片的宽度
        int height = 300;            //图片的高度
        String format = "png";        //图片的格式\

        /**
         * 主文件夹路径
         */
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String datePath = sdf.format(new Date());
        String folder = "/home/data/automation/qrCode/" + datePath;
        File packageFile = new File(folder);
        if (!packageFile.isDirectory()) { // 目录不存在创建文件夹
            packageFile.mkdirs();
        }
        String filePath = folder + "/" + StringUtils.uuid() + ".png";
        /**
         * 定义二维码的参数
         */
        HashMap hints = new HashMap();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");    //指定字符编码为“utf-8”
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);  //指定二维码的纠错等级为中级
        hints.put(EncodeHintType.MARGIN, 2);    //设置图片的边距
        /**
         * 生成二维码
         */
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            Path file = new File(filePath).toPath();
            MatrixToImageWriter.writeToPath(bitMatrix, format, file);
            return filePath;
        } catch (Exception e) {
            e.printStackTrace();
            return filePath;
        }
    }

    /**
     * 保存二维码图片到指定的路径
     *
     * @param filePath 指定的路径
     * @param content  二维码的内存(字符串)
     */
    public static void createQRCode(String filePath, String content) {
        int width = 300;            //图片的宽度
        int height = 300;            //图片的高度
        String format = "png";        //图片的格式\

        /**
         * 定义二维码的参数
         */
        HashMap hints = new HashMap();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");    //指定字符编码为“utf-8”
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);  //指定二维码的纠错等级为中级
        hints.put(EncodeHintType.MARGIN, 2);    //设置图片的边距

        /**
         * 生成二维码
         */
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            Path file = new File(filePath).toPath();
            MatrixToImageWriter.writeToPath(bitMatrix, format, file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getContentFromQRCode(String filePath) {
        MultiFormatReader formatReader = new MultiFormatReader();
        File file = new File(filePath);
        BufferedImage image;
        try {
            image = ImageIO.read(file);
            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer
                    (new BufferedImageLuminanceSource(image)));
            HashMap hints = new HashMap();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");    //指定字符编码为“utf-8”
            Result result = formatReader.decode(binaryBitmap, hints);
            return result.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 生成二维码图片字节数组,可将字节数组写入文件、经base64编码后写入FreeMarker模版等操作
     *
     * @param content 二维码内容
     * @param width   宽
     * @param height  高
     * @param margin  外边距
     * @return 二维码对应的字节数组
     * @throws Exception
     */
    public byte[] getQRCodeBytes(String content, int width, int height, int margin) throws Exception {
        Hashtable<EncodeHintType, Object> hintTypes = new Hashtable<EncodeHintType, Object>();
        ByteArrayOutputStream outputStream = null;

        hintTypes.put(EncodeHintType.CHARACTER_SET, CharacterSetECI.UTF8);//设置编码
        hintTypes.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//设置容错级别
        hintTypes.put(EncodeHintType.MARGIN, margin);//设置外边距

        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hintTypes);//获取二维码

            //将二维码写入图片
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            for (int i = 0; i < width; i++) {
                for (int j = 0; j < height; j++) {
                    bufferedImage.setRGB(i, j, bitMatrix.get(i, j) ? Color.RED.getRGB() : Color.WHITE.getRGB());
                }
            }

            //将图片转为字节数组
            outputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "png", outputStream);
            return outputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }

    /**
     * 二维码生成解析工具类
     *
     * @data 2018-11-2 10:23:14
     */
    public static class QRCodeUtil {

        // 二维码颜色==黑色
        private static final int BLACK = 0xFF000000;
        // 二维码颜色==白色
        private static final int WHITE = 0xFFFFFFFF;
        // 二维码图片格式==jpg和png两种
        private static final List<String> IMAGE_TYPE = new ArrayList<String>();

        static {
            IMAGE_TYPE.add("jpg");
            IMAGE_TYPE.add("png");
        }

        /**
         * zxing方式生成二维码
         * 注意:
         * 1,文本生成二维码的方法独立出来,返回image流的形式,可以输出到页面
         * 2,设置容错率为最高,一般容错率越高,图片越不清晰, 但是只有将容错率设置高一点才能兼容logo图片
         * 3,logo图片默认占二维码图片的20%,设置太大会导致无法解析
         *
         * @param content  二维码包含的内容,文本或网址
         * @param path     生成的二维码图片存放位置
         * @param size     生成的二维码图片尺寸 可以自定义或者默认(250)
         * @param logoPath logo的存放位置
         */
        public static boolean zxingCodeCreate(String content, String path, Integer size, String logoPath) {
            try {
                //图片类型
                String imageType = "jpg";
                //获取二维码流的形式,写入到目录文件中
                BufferedImage image = getBufferedImage(content, size, logoPath);
                //获得随机数
                Random random = new Random();
                //生成二维码存放文件
                File file = new File(path + random.nextInt(1000) + ".jpg");
                if (!file.exists()) {
                    file.mkdirs();
                }
                ImageIO.write(image, imageType, file);
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }

        /**
         * 二维码流的形式,包含文本内容
         *
         * @param content  二维码文本内容
         * @param size     二维码尺寸
         * @param logoPath logo的存放位置
         * @return
         */
        public static BufferedImage getBufferedImage(String content, Integer size, String logoPath) {
            if (size == null || size <= 0) {
                size = 250;
            }
            BufferedImage image = null;
            try {
                // 设置编码字符集
                Map<EncodeHintType, Object> hints = new HashMap<>();
                //设置编码
                hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
                //设置容错率最高
                hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
                hints.put(EncodeHintType.MARGIN, 1);
                // 1、生成二维码
                MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
                BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, size, size, hints);
                // 2、获取二维码宽高
                int codeWidth = bitMatrix.getWidth();
                int codeHeight = bitMatrix.getHeight();
                // 3、将二维码放入缓冲流
                image = new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);
                for (int i = 0; i < codeWidth; i++) {
                    for (int j = 0; j < codeHeight; j++) {
                        // 4、循环将二维码内容定入图片
                        image.setRGB(i, j, bitMatrix.get(i, j) ? BLACK : WHITE);
                    }
                }
                //判断是否写入logo图片
                if (logoPath != null && !"".equals(logoPath)) {
                    File logoPic = new File(logoPath);
                    if (logoPic.exists()) {
                        Graphics2D g = image.createGraphics();
                        BufferedImage logo = ImageIO.read(logoPic);
                        int widthLogo = logo.getWidth(null) > image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10) : logo.getWidth(null);
                        int heightLogo = logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10) : logo.getHeight(null);
                        int x = (image.getWidth() - widthLogo) / 2;
                        int y = (image.getHeight() - heightLogo) / 2;
                        // 开始绘制图片
                        g.drawImage(logo, x, y, widthLogo, heightLogo, null);
                        g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
                        //边框宽度
                        g.setStroke(new BasicStroke(2));
                        //边框颜色
                        g.setColor(Color.WHITE);
                        g.drawRect(x, y, widthLogo, heightLogo);
                        g.dispose();
                        logo.flush();
                        image.flush();
                    }
                }
            } catch (WriterException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return image;
        }

        /**
         * 给二维码图片添加Logo
         *
         * @param qrPic   二维码图片
         * @param logoPic logo图片
         * @param path    合成后的图片存储目录
         */
        public static boolean zxingCodeCreate(File qrPic, File logoPic, String path) {
            try {
                String imageType = path.substring(path.lastIndexOf(".") + 1).toLowerCase();
                if (!IMAGE_TYPE.contains(imageType)) {
                    return false;
                }

                if (!qrPic.isFile() && !logoPic.isFile()) {
                    return false;
                }

                //读取二维码图片,并构建绘图对象

                BufferedImage image = ImageIO.read(qrPic);
                Graphics2D g = image.createGraphics();
                //读取Logo图片
                BufferedImage logo = ImageIO.read(logoPic);
                //设置logo的大小,最多20%0
                int widthLogo = logo.getWidth(null) > image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10) : logo.getWidth(null);
                int heightLogo = logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10) : logo.getHeight(null);
                // 计算图片放置位置,默认在中间
                int x = (image.getWidth() - widthLogo) / 2;
                int y = (image.getHeight() - heightLogo) / 2;
                // 开始绘制图片
                g.drawImage(logo, x, y, widthLogo, heightLogo, null);
                g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
                //边框宽度
                g.setStroke(new BasicStroke(2));
                //边框颜色
                g.setColor(Color.WHITE);
                g.drawRect(x, y, widthLogo, heightLogo);
                g.dispose();
                logo.flush();
                image.flush();
                File newFile = new File(path);
                if (!newFile.exists()) {
                    newFile.mkdirs();
                }
                ImageIO.write(image, imageType, newFile);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }


        /**
         * 二维码的解析方法
         *
         * @param path 二维码图片目录
         * @return
         */
        public static Result zxingCodeAnalyze(String path) {
            try {
                MultiFormatReader formatReader = new MultiFormatReader();
                File file = new File(path);
                if (file.exists()) {
                    BufferedImage image = ImageIO.read(file);
                    LuminanceSource source = new BufferedImageLuminanceSource(image);
                    Binarizer binarizer = new HybridBinarizer(source);
                    BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
                    Map hints = new HashMap();
                    hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
                    Result result = formatReader.decode(binaryBitmap, hints);
                    return result;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值