| 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")); | 
|     } | 
|   | 
| } |