Java 生成二维码 (包含 base64 存在的形式)

Java 生成二维码

1. 导包

<!-- 生成二维码 -->
<dependency>
	<groupId>com.google.zxing</groupId>
	<artifactId>javase</artifactId>
	<version>3.4.0</version>
</dependency>

2. 工具类

package com.springCloud.user.config.QRCode;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Base64;

/**
 * bases64 与 照片, 照片流的相互转化
 */

public class ImgBase64 {

    private static Base64.Encoder encoder = Base64.getEncoder();

    private static Base64.Decoder decoder = Base64.getDecoder();

    /**
     * 照片转化为 bases64
     *
     * @param path   照片路径
     * @param suffix 照片格式
     * @return String
     */
    public static String getImageBinary(String path, String suffix) {
        File file = new File(path);
        try {
            BufferedImage read = ImageIO.read(file);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(read, suffix, byteArrayOutputStream);
            byte[] bytes = byteArrayOutputStream.toByteArray();
            return encoder.encodeToString(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 照片流转化为 bases64
     *
     * @param bufferedImage 照片流
     * @param suffix        照片格式
     * @return String
     */
    public static String bufferedImageToBase64String(BufferedImage bufferedImage, String suffix) {
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, suffix, byteArrayOutputStream);
            byte[] bytes = byteArrayOutputStream.toByteArray();
            return encoder.encodeToString(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * bases64 转化为照片流
     *
     * @param base64String bases64
     * @return String
     */
    public static BufferedImage base64StringToBufferedImage(String base64String) {
        try {
            byte[] decode = decoder.decode(base64String);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decode);
            return ImageIO.read(byteArrayInputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * bases64 转化为照片
     *
     * @param base64String bases64
     * @param path         照片生成的路径
     * @param suffix       照片格式
     */
    public static void base64StringToImage(String base64String, String path, String suffix) {
        try {
            byte[] decode = decoder.decode(base64String);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decode);
            BufferedImage read = ImageIO.read(byteArrayInputStream);
            File f1 = new File(path);
            ImageIO.write(read, suffix, f1);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

3. 工具类

该工具包括的功能:

  1. 将生成二维码放在指定路径
  2. 将生成二维码以 base64 字符串形式存在
  3. 指定 LOGO 照片路径嵌入中生成二维码
  4. 指定 LOGO 的 base64 字符串嵌入中生成二维码
package com.springCloud.user.config.QRCode;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Hashtable;
import java.util.Random;

/**
 * 生成二维码
 */

public class QRCode {

    // 编码
    private static final String CHARSET = "utf-8";
    // 格式
    private static final String FORMAT_NAME = "png";
    // 二维码尺寸
    private static final int QR_CODE_SIZE = 300;
    // LOGO 宽度
    private static final int WIDTH = 60;
    // LOGO 高度
    private static final int HEIGHT = 60;

    private static BufferedImage createImage(String content, String imgOrBase64, boolean judgeImgOrBase64, boolean needCompress) throws Exception {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
        //  生成二维码的容错等级 M 为 中级
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        // 生成二维码的字符编码
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        // 生成二维码的图片的黑线直接的边距
        hints.put(EncodeHintType.MARGIN, 1);
        // 二维码的生成
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, hints);
        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) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        // 插入图片
        QRCode.insertImage(image, imgOrBase64, judgeImgOrBase64, needCompress);
        return image;
    }

    /**
     * 插入 LOGO
     *
     * @param source           二维码图片
     * @param imgOrBase64      LOGO 图片的存在形式
     * @param judgeImgOrBase64 判断 LOGO 存在形式
     * @param needCompress     是否压缩
     * @throws Exception Exception
     */
    private static void insertImage(BufferedImage source, String imgOrBase64, boolean judgeImgOrBase64, boolean needCompress) throws Exception {
        Image bufferedImage;
        if (judgeImgOrBase64) {
            File file = new File(imgOrBase64);
            if (!file.exists()) {
                System.err.println("" + imgOrBase64 + "   该文件不存在!");
                return;
            }
            bufferedImage = ImageIO.read(new File(imgOrBase64));
        } else {
            bufferedImage = ImgBase64.base64StringToBufferedImage(imgOrBase64);
        }
        if (bufferedImage != null) {
            int width = bufferedImage.getWidth(null);
            int height = bufferedImage.getHeight(null);

            // 压缩 LOGO
            if (needCompress) {
                if (width > WIDTH) {
                    width = WIDTH;
                }
                if (height > HEIGHT) {
                    height = HEIGHT;
                }
                Image image = bufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
                BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                Graphics g = tag.getGraphics();
                // 绘制缩小后的图
                g.drawImage(image, 0, 0, null);
                g.dispose();
                bufferedImage = image;
            }
            // 插入 LOGO
            Graphics2D graph = source.createGraphics();
            int x = (QR_CODE_SIZE - width) / 2;
            int y = (QR_CODE_SIZE - height) / 2;
            graph.drawImage(bufferedImage, x, y, width, height, null);
            Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
            graph.setStroke(new BasicStroke(3f));
            graph.draw(shape);
            graph.dispose();
        }
    }

    /**
     * 生成二维码 (内嵌 LOGO)
     *
     * @param content          内容
     * @param imgOrBase64      LOGO 存在形式
     * @param judgeImgOrBase64 判断 LOGO 存在形式
     * @param destPath         存放目录
     * @param needCompress     是否压缩 LOGO
     * @throws Exception Exception
     */
    public String encode(String content, String imgOrBase64, boolean judgeImgOrBase64, String destPath, boolean needCompress) throws Exception {
        BufferedImage image = QRCode.createImage(content, imgOrBase64, judgeImgOrBase64, needCompress);
        mkdirs(destPath);
        String file = new Random().nextInt(99999999) + "." + FORMAT_NAME;
        ImageIO.write(image, FORMAT_NAME, new File(destPath + "/" + file));
        return file;
    }

    /**
     * 生成二维码 base64 (内嵌 LOGO)
     *
     * @param content     内容
     * @param imgOrBase64 LOGO 存在形式
     * @return base64String
     * @throws Exception Exception
     */
    public String encodeBase64String(String content, String imgOrBase64, boolean needCompress) throws Exception {
        BufferedImage image = QRCode.createImage(content, imgOrBase64, false, needCompress);
        return ImgBase64.bufferedImageToBase64String(image, FORMAT_NAME);
    }

    /**
     * 当文件夹不存在时, mkdirs 会自动创建多层目录, 区别于 mkdir. (mkdir 如果父目录不存在则会抛出异常)
     *
     * @param destPath 存放目录
     */
    private static void mkdirs(String destPath) {
        File file = new File(destPath);
        if (!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
    }

    /**
     * 解析二维码
     *
     * @param file 二维码图片
     * @return String
     * @throws Exception Exception
     */
    public static String decode(File file) throws Exception {
        BufferedImage image;
        image = ImageIO.read(file);
        if (image == null) {
            return null;
        }
        BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
        Result result;
        Hashtable<DecodeHintType, Object> hints = new Hashtable<>();
        hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
        result = new MultiFormatReader().decode(bitmap, hints);
        return result.getText();
    }

    /**
     * 解析二维码
     *
     * @param path 二维码图片地址
     * @return String
     * @throws Exception Exception
     */
    public static String decode(String path) throws Exception {
        return QRCode.decode(new File(path));
    }

}

猜你喜欢

转载自blog.csdn.net/YKenan/article/details/106317736
今日推荐