package com.doumee.core.utils; 
 | 
  
 | 
import com.google.zxing.BarcodeFormat; 
 | 
import com.google.zxing.EncodeHintType; 
 | 
import com.google.zxing.MultiFormatWriter; 
 | 
import com.google.zxing.common.BitMatrix; 
 | 
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)); 
 | 
//    } 
 | 
} 
 |