| package com.doumee.core.utils; | 
|   | 
| import com.google.zxing.*; | 
| 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.io.InputStream; | 
| import java.io.OutputStream; | 
| import java.util.Hashtable; | 
|   | 
| /** | 
|  * 二维码生成工具类 | 
|  */ | 
| public class QrCodeUtils { | 
|   | 
|     private static final String CHARSET = "utf-8"; | 
|     public static final String FORMAT = "JPG"; | 
|     // 二维码尺寸 | 
|     private static final int QRCODE_SIZE = 300; | 
|     // LOGO宽度 | 
|     private static final int LOGO_WIDTH = 60; | 
|     // LOGO高度 | 
|     private static final int LOGO_HEIGHT = 60; | 
|   | 
|     /** | 
|      * 生成二维码 | 
|      * | 
|      * @param content      二维码内容 | 
|      * @param logoPath     logo地址 | 
|      * @param needCompress 是否压缩logo | 
|      * @return 图片 | 
|      */ | 
|     public static BufferedImage createImage(String content, String logoPath, boolean needCompress) throws Exception { | 
|         Hashtable<EncodeHintType, Object> hints = new Hashtable<>(); | 
|         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); | 
|         hints.put(EncodeHintType.CHARACTER_SET, CHARSET); | 
|         hints.put(EncodeHintType.MARGIN, 1); | 
|         BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_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); | 
|             } | 
|         } | 
|         if (logoPath == null || "".equals(logoPath)) { | 
|             return image; | 
|         } | 
|         // 插入图片 | 
|         QrCodeUtils.insertImage(image, logoPath, needCompress); | 
|         return image; | 
|     } | 
|   | 
|     /** | 
|      * 插入LOGO | 
|      * | 
|      * @param source       二维码图片 | 
|      * @param logoPath     LOGO图片地址 | 
|      * @param needCompress 是否压缩 | 
|      */ | 
|     private static void insertImage(BufferedImage source, String logoPath, | 
|                                     boolean needCompress) throws Exception { | 
|         File file = new File(logoPath); | 
|         if (!file.exists()) { | 
|             System.err.println(""+logoPath+"   该文件不存在!"); | 
|             return; | 
|         } | 
|         Image src = ImageIO.read(new File(logoPath)); | 
|         int width = src.getWidth(null); | 
|         int height = src.getHeight(null); | 
|         if (needCompress) { // 压缩LOGO | 
|             if (width > LOGO_WIDTH) { | 
|                 width = LOGO_WIDTH; | 
|             } | 
|             if (height > LOGO_HEIGHT) { | 
|                 height = LOGO_HEIGHT; | 
|             } | 
|             Image image = src.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(); | 
|             src = image; | 
|         } | 
|         // 插入LOGO | 
|         Graphics2D graph = source.createGraphics(); | 
|         int x = (QRCODE_SIZE - width) / 2; | 
|         int y = (QRCODE_SIZE - height) / 2; | 
|         graph.drawImage(src, 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(); | 
|     } | 
|   | 
|     /** | 
|      * 生成二维码(指定路径保存) | 
|      * | 
|      * @param content 内容 | 
|      * @param imgPath logo图片地址(内嵌图片) | 
|      * @param destPath 生成二维码存放地址 | 
|      * @param needCompress 是否压缩logo | 
|      */ | 
|     public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception { | 
|         BufferedImage image = QrCodeUtils.createImage(content, imgPath, needCompress); | 
|         mkdirs(destPath); | 
|         ImageIO.write(image, FORMAT, new File(destPath)); | 
|     } | 
|   | 
|     /** | 
|      * 生成二维码(直接将二维码以图片输出流返回) | 
|      * | 
|      * @param content 内容 | 
|      * @param imgPath logo图片地址(内嵌图片) | 
|      * @param needCompress 是否压缩logo | 
|      * @return 二维码图片 | 
|      */ | 
|     public static BufferedImage encode(String content, String imgPath, boolean needCompress) throws Exception { | 
|         return QrCodeUtils.createImage(content, imgPath, needCompress); | 
|     } | 
|   | 
|     /** | 
|      * 创建多级文件 | 
|      * | 
|      * @param destPath 目标目录 | 
|      */ | 
|     public static void mkdirs(String destPath) { | 
|         File file = new File(destPath); | 
|         // 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常) | 
|         if (!file.exists() && !file.isDirectory()) { | 
|             file.mkdirs(); | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 生成二维码(内嵌LOGO) | 
|      * | 
|      * @param content      内容 | 
|      * @param logoPath     LOGO地址 | 
|      * @param output       输出流 | 
|      * @param needCompress 是否压缩LOGO | 
|      */ | 
|     public static void encode(String content, String logoPath, OutputStream output, boolean needCompress) | 
|             throws Exception { | 
|   | 
|         BufferedImage image = QrCodeUtils.createImage(content, logoPath, needCompress); | 
|         ImageIO.write(image, FORMAT, output); | 
|     } | 
|   | 
|     /** | 
|      * 获取指定文件的输入流,获取logo | 
|      * | 
|      * @param logoPath 文件的路径 | 
|      * @return 输入流 | 
|      */ | 
|     public static InputStream getResourceAsStream(String logoPath) { | 
|         return QrCodeUtils.class.getResourceAsStream(logoPath); | 
|     } | 
|   | 
| /*    *//** | 
|      * 解析二维码 | 
|      * | 
|      * @param file 二维码图片 | 
|      * @return 解析结果 | 
|      *//* | 
|     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 二维码解析结果 | 
|      */ | 
| //    public static String decode(String path) throws Exception { | 
| //        return QrCodeUtils.decode(new File(path)); | 
| //    } | 
| } |