package com.dy.common.util; 
 | 
  
 | 
import cn.hutool.core.codec.Base64; 
 | 
import cn.hutool.core.util.ObjectUtil; 
 | 
import cn.hutool.core.util.StrUtil; 
 | 
import com.google.zxing.*; 
 | 
import com.google.zxing.client.j2se.BufferedImageLuminanceSource; 
 | 
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.HybridBinarizer; 
 | 
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 
 | 
  
 | 
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.util.Hashtable; 
 | 
  
 | 
public class QrCodeGenerator { 
 | 
  
 | 
  
 | 
    private static final String DEFAULT_CHAR_SET = "UTF-8"; 
 | 
  
 | 
    private static final String DEFAULT_FORMAT_NAME = "JPG"; 
 | 
  
 | 
  
 | 
    // 二维码宽度 
 | 
    private static final int DEFAULT_QR_CODE_WIDTH = 300; 
 | 
    // 二维码高度 
 | 
    private static final int DEFAULT_QR_CODE_HEIGHT = 300; 
 | 
  
 | 
    /** 
 | 
     * 创建BitMatrix比特矩阵 
 | 
     * @Param contents 二维码里的内容 
 | 
     * @Param width 二维码宽度 
 | 
     * @param height 二维码高度 
 | 
     * @return com.google.zxing.common.BitMatrix 
 | 
     */ 
 | 
    public static BitMatrix createBitMatrix(String contents, int width , int height) throws WriterException, IOException { 
 | 
        if (ObjectUtil.isNull(width)) { 
 | 
            width = DEFAULT_QR_CODE_WIDTH; 
 | 
        } 
 | 
        if (ObjectUtil.isNull(height)) { 
 | 
            height = DEFAULT_QR_CODE_HEIGHT; 
 | 
        } 
 | 
  
 | 
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>(); 
 | 
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 纠错等级L,M,Q,H 
 | 
        hints.put(EncodeHintType.CHARACTER_SET, DEFAULT_CHAR_SET);// 编码utf-8 
 | 
        hints.put(EncodeHintType.MARGIN, 1);  // 边距 
 | 
  
 | 
        // 创建比特矩阵 
 | 
        BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, 
 | 
                BarcodeFormat.QR_CODE, width, height, hints); 
 | 
        return bitMatrix; 
 | 
  
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 创建二维码,返回字节数组 
 | 
     * @Param contents 二维码里的内容 
 | 
     * @Param imageFormat 图片后缀名 
 | 
     * @Param width 二维码宽度 
 | 
     * @param height 二维码高度 
 | 
     * @return byte[] 
 | 
     */ 
 | 
    public static byte[] createQrCode(String contents , String imageFormat , int width , int height) throws WriterException, IOException { 
 | 
        if (StrUtil.isBlank(imageFormat)){ 
 | 
            imageFormat = DEFAULT_FORMAT_NAME; 
 | 
        } 
 | 
        BitMatrix bitMatrix = createBitMatrix(contents , width, height); 
 | 
        ByteArrayOutputStream os = new ByteArrayOutputStream(); 
 | 
        MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, os); 
 | 
        return os.toByteArray(); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 创建二维码,返回base64字符串 
 | 
     * @Date 2023/09/24 22:30 
 | 
     * @Param contents 二维码里的内容 
 | 
     * @Param imageFormat 图片后缀名 
 | 
     * @Param width 二维码宽度 
 | 
     * @param height 二维码高度 
 | 
     * @return byte[] 
 | 
     */ 
 | 
    public static String createQrCodeBase64(String contents , String imageFormat , int width , int height) throws WriterException, IOException { 
 | 
        byte[] bytes = createQrCode(contents , imageFormat , width, height); 
 | 
        return Base64.encode(bytes); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 解码二维码 
 | 
     * @Param [image] 
 | 
     * @return java.lang.String 
 | 
     */ 
 | 
    public static String decodeQrCode(BufferedImage image) throws Exception { 
 | 
        if (image == null) return StrUtil.EMPTY; 
 | 
        BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image); 
 | 
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); 
 | 
        Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(); 
 | 
        hints.put(DecodeHintType.CHARACTER_SET, DEFAULT_CHAR_SET); 
 | 
        Result result = new MultiFormatReader().decode(bitmap, hints); 
 | 
        return result.getText(); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 转换为BufferedImage 
 | 
     * @Param [bitMatrix] 
 | 
     * @return java.awt.image.BufferedImage 
 | 
     */ 
 | 
    public static BufferedImage toBufferedImage(BitMatrix bitMatrix) throws IOException, WriterException { 
 | 
        MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF); 
 | 
        BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig); 
 | 
        return bufferedImage; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 给二维码添加logo 
 | 
     * @Param [bufferedImage, logoFile] 
 | 
     * @return java.awt.image.BufferedImage 
 | 
     */ 
 | 
    public static BufferedImage addQrCodeLogo(BufferedImage bufferedImage, File logoFile) throws IOException { 
 | 
        Graphics2D graphics = bufferedImage.createGraphics(); 
 | 
        int matrixWidth = bufferedImage.getWidth(); 
 | 
        int matrixHeigh = bufferedImage.getHeight(); 
 | 
  
 | 
        // 读取logo图片文件 
 | 
        BufferedImage logo = ImageIO.read(logoFile); 
 | 
        int logoWidth = logo.getWidth(); 
 | 
        int logoHeight = logo.getHeight(); 
 | 
  
 | 
        //  计算logo放置位置 
 | 
        int x = bufferedImage.getWidth()  / 5*2; 
 | 
        int y = bufferedImage.getHeight() / 5*2; 
 | 
        int width = matrixWidth / 5; 
 | 
        int height = matrixHeigh / 5; 
 | 
  
 | 
        // 开始绘制图片 
 | 
        graphics.drawImage(logo, x, y, width, height, null); 
 | 
        graphics.drawRoundRect(x, y, logoWidth, logoHeight, 15, 15); 
 | 
        graphics.setStroke(new BasicStroke(5.0F, 1, 1)); 
 | 
        graphics.setColor(Color.white); 
 | 
        graphics.drawRect(x, y, logoWidth, logoHeight); 
 | 
  
 | 
        graphics.dispose(); 
 | 
        bufferedImage.flush(); 
 | 
        return bufferedImage; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * BufferedImage转字节数组 
 | 
     * @param image 
 | 
     * @param imageFormat 
 | 
     * @return 
 | 
     */ 
 | 
    public static byte[] bufferedImageToByteArray(BufferedImage image, String imageFormat) { 
 | 
        if (StrUtil.isBlank(imageFormat)){ 
 | 
            imageFormat = DEFAULT_FORMAT_NAME; 
 | 
        } 
 | 
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
 | 
        try { 
 | 
            // 使用ImageIO将BufferedImage写入outputStream 
 | 
            ImageIO.write(image, imageFormat, outputStream); 
 | 
            return outputStream.toByteArray(); 
 | 
        } catch (IOException e) { 
 | 
            e.printStackTrace(); 
 | 
            return null; 
 | 
        } finally { 
 | 
            try { 
 | 
                outputStream.close(); 
 | 
            } catch (IOException e) { 
 | 
                e.printStackTrace(); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public static void main(String[] args) throws Exception { 
 | 
        BufferedImage bufferedImage = toBufferedImage(createBitMatrix("https://blog.csdn.net", 300, 300)); 
 | 
        ImageIO.write(bufferedImage, "JPG", new File("D:/qrcode.jpg")); 
 | 
  
 | 
        System.out.println(decodeQrCode(bufferedImage)); 
 | 
  
 | 
        BufferedImage logoQrCode = addQrCodeLogo(bufferedImage, new File("D://logo.png")); 
 | 
        ImageIO.write(logoQrCode, "JPG", new File("D:/logoQrcode.jpg")); 
 | 
    } 
 | 
  
 | 
} 
 |