admin
2024-07-25 47e3087067abd35e6337c011f96d2338c0bb1aae
src/main/java/org/yeshi/utils/QRCodeUtil.java
@@ -26,327 +26,309 @@
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
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;
/**
 * 二维码生成
 *
 * @author Administrator
 *
 * @author Administrator
 */
public class QRCodeUtil {
   private static final String CHARSET = "UTF-8";
   private static final String FORMAT_NAME = "JPG";
   // 二维码尺寸
   int QRCODE_SIZE = 200;
   // LOGO宽度
   int WIDTH = 60;
   // LOGO高度
   int HEIGHT = 60;
    private static final String CHARSET = "UTF-8";
    private static final String FORMAT_NAME = "JPG";
   static QRCodeUtil qrCodeUtil;
    // 二维码尺寸
    int QRCODE_SIZE = 200;
    // LOGO宽度
    int WIDTH = 60;
    // LOGO高度
    int HEIGHT = 60;
   public static QRCodeUtil getInstance(int size) {
      if (qrCodeUtil == null) {
         qrCodeUtil = new QRCodeUtil();
      }
      qrCodeUtil.QRCODE_SIZE = size;
      return qrCodeUtil;
   }
    static QRCodeUtil qrCodeUtil;
   public static QRCodeUtil getInstance(int size, int imgSize) {
      if (qrCodeUtil == null) {
         qrCodeUtil = new QRCodeUtil();
      }
      qrCodeUtil.QRCODE_SIZE = size;
      qrCodeUtil.HEIGHT = imgSize;
      qrCodeUtil.WIDTH = imgSize;
      return qrCodeUtil;
   }
    public static QRCodeUtil getInstance(int size) {
        if (qrCodeUtil == null) {
            qrCodeUtil = new QRCodeUtil();
        }
        qrCodeUtil.QRCODE_SIZE = size;
        return qrCodeUtil;
    }
   /**
    * user: Rex date: 2016年12月29日 上午12:31:29
    *
    * @param content
    *            二维码内容
    * @param logoImgPath
    *            Logo
    * @param needCompress
    *            是否压缩Logo
    * @return 返回二维码图片
    * @throws WriterException
    * @throws IOException
    *             BufferedImage TODO 创建二维码图片
    */
   private BufferedImage createImage(String content, InputStream logoImg, boolean needCompress)
         throws WriterException, IOException {
      Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
      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 (logoImg == null) {
         return image;
      }
      // 插入图片
      insertImage(image, logoImg, needCompress);
      return image;
   }
    public static QRCodeUtil getInstance(int size, int imgSize) {
        if (qrCodeUtil == null) {
            qrCodeUtil = new QRCodeUtil();
        }
        qrCodeUtil.QRCODE_SIZE = size;
        qrCodeUtil.HEIGHT = imgSize;
        qrCodeUtil.WIDTH = imgSize;
        return qrCodeUtil;
    }
   /**
    * user: Rex date: 2016年12月29日 上午12:31:29
    *
    * @param content
    *            二维码内容
    * @param logoImgPath
    *            Logo
    * @param needCompress
    *            是否压缩Logo
    * @return 返回二维码图片
    * @throws WriterException
    * @throws IOException
    *             BufferedImage TODO 创建二维码图片
    */
   private BufferedImage createImageDeleteWhite(String content, InputStream logoImg, boolean needCompress)
         throws WriterException, IOException {
      Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
      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);
      //调用去除白边方法
    /**
     * user: Rex date: 2016年12月29日 上午12:31:29
     *
     * @param content      二维码内容
     * @param logoImgPath  Logo
     * @param needCompress 是否压缩Logo
     * @return 返回二维码图片
     * @throws WriterException
     * @throws IOException
     */
    private BufferedImage createImage(String content, InputStream logoImg, boolean needCompress)
            throws WriterException, IOException {
        return this.createImage(content, logoImg, 0xFF000000, 0xFFFFFFFF, needCompress);
    }
    public BufferedImage createImage(String content, InputStream logoImg, int color, int bgColor, boolean needCompress)
            throws WriterException, IOException {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        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) ? color : bgColor);
            }
        }
        if (logoImg == null) {
            return image;
        }
        if (logoImg != null) {
            // 插入图片
            insertImage(image, logoImg, needCompress);
        }
        return image;
    }
    /**
     * user: Rex date: 2016年12月29日 上午12:31:29
     *
     * @param content      二维码内容
     * @param logoImgPath  Logo
     * @param needCompress 是否压缩Logo
     * @return 返回二维码图片
     * @throws WriterException
     * @throws IOException
     */
    private BufferedImage createImageDeleteWhite(String content, InputStream logoImg, boolean needCompress)
            throws WriterException, IOException {
        return createImageDeleteWhite(content, logoImg, 0xFF000000, 0xFFFFFFFF, needCompress);
    }
    public BufferedImage createImageDeleteWhite(String content, InputStream logoImg, int color, int bgColor, boolean needCompress)
            throws WriterException, IOException {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        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);
        //调用去除白边方法
        bitMatrix = deleteWhite(bitMatrix);
      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 (logoImg == null) {
         return image;
      }
      // 插入图片
      insertImage(image, logoImg, needCompress);
      return image;
   }
   /**
    * user: Rex date: 2016年12月29日 上午12:30:09
    *
    * @param source
    *            二维码图片
    * @param logoImgPath
    *            Logo
    * @param needCompress
    *            是否压缩Logo
    * @throws IOException
    *             void TODO 添加Logo
    */
   private void insertImage(BufferedImage source, InputStream logoImg, boolean needCompress) throws IOException {
      Image src = ImageIO.read(logoImg);
      int width = src.getWidth(null);
      int height = src.getHeight(null);
      if (needCompress) { // 压缩LOGO
         if (width > WIDTH) {
            width = WIDTH;
         }
         if (height > HEIGHT) {
            height = HEIGHT;
         }
        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) ? color : bgColor);
            }
        }
        if (logoImg == null) {
            return image;
        }
         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;
      }
        // 插入图片
        if (logoImg != null) {
            insertImage(image, logoImg, needCompress);
        }
        return 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();
   }
    /**
     * user: Rex date: 2016年12月29日 上午12:30:09
     *
     * @param source       二维码图片
     * @param logoImgPath  Logo
     * @param needCompress 是否压缩Logo
     * @throws IOException void TODO 添加Logo
     */
    private void insertImage(BufferedImage source, InputStream logoImg, boolean needCompress) throws IOException {
        Image src = ImageIO.read(logoImg);
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        if (needCompress) { // 压缩LOGO
            if (width > WIDTH) {
                width = WIDTH;
            }
   /**
    * user: Rex date: 2016年12月29日 上午12:32:32
    *
    * @param content
    *            二维码内容
    * @param logoImgPath
    *            Logo
    * @param destPath
    *            二维码输出路径
    * @param needCompress
    *            是否压缩Logo
    * @throws Exception
    *             void TODO 生成带Logo的二维码
    */
   public void encode(String content, InputStream logoImg, String destPath, boolean needCompress) throws Exception {
      BufferedImage image = createImage(content, logoImg, needCompress);
      ImageIO.write(image, FORMAT_NAME, new File(destPath));
   }
            if (height > HEIGHT) {
                height = HEIGHT;
            }
   /**
    * user: Rex date: 2016年12月29日 上午12:35:44
    *
    * @param content
    *            二维码内容
    * @param destPath
    *            二维码输出路径
    * @throws Exception
    *             void TODO 生成不带Logo的二维码
    */
   public void encode(String content, String destPath) throws Exception {
      encode(content, null, destPath, false);
   }
            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;
        }
   public InputStream encode(String content) throws Exception {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      encode(content, null, out, false);
      return new ByteArrayInputStream(out.toByteArray());
   }
        // 插入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();
    }
   public InputStream encodeDeleteWhite(String content) throws Exception {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      encodeDeleteWhite(content, null, out, false);
      return new ByteArrayInputStream(out.toByteArray());
   }
   /**
    * user: Rex date: 2016年12月29日 上午12:36:58
    *
    * @param content
    *            二维码内容
    * @param logoImgPath
    *            Logo
    * @param output
    *            输出流
    * @param needCompress
    *            是否压缩Logo
    * @throws Exception
    *             void TODO 生成带Logo的二维码,并输出到指定的输出流
    */
   public void encode(String content, InputStream logoImg, OutputStream output, boolean needCompress)
         throws Exception {
      BufferedImage image = createImage(content, logoImg, needCompress);
      ImageIO.write(image, FORMAT_NAME, output);
   }
    /**
     * user: Rex date: 2016年12月29日 上午12:32:32
     *
     * @param content      二维码内容
     * @param logoImgPath  Logo
     * @param destPath     二维码输出路径
     * @param needCompress 是否压缩Logo
     * @throws Exception void TODO 生成带Logo的二维码
     */
    public void encode(String content, InputStream logoImg, String destPath, boolean needCompress) throws Exception {
        BufferedImage image = createImage(content, logoImg, needCompress);
        ImageIO.write(image, FORMAT_NAME, new File(destPath));
    }
   /**
    *
    * @param content
    * @param logoImg
    * @param output
    *            二进制输出流
    * @param needCompress
    * @throws Exception
    */
   public void encode(String content, InputStream logoImg, ByteArrayOutputStream output, boolean needCompress)
         throws Exception {
      BufferedImage image = createImage(content, logoImg, needCompress);
      ImageIO.write(image, FORMAT_NAME, output);
   }
   /**
    *
    * @param content
    * @param logoImg
    * @param output
    *            二进制输出流
    * @param needCompress
    * @throws Exception
    */
   public void encodeDeleteWhite(String content, InputStream logoImg, ByteArrayOutputStream output, boolean needCompress)
         throws Exception {
      BufferedImage image = createImageDeleteWhite(content, logoImg, needCompress);
      ImageIO.write(image, FORMAT_NAME, output);
   }
    /**
     * user: Rex date: 2016年12月29日 上午12:35:44
     *
     * @param content  二维码内容
     * @param destPath 二维码输出路径
     * @throws Exception void TODO 生成不带Logo的二维码
     */
    public void encode(String content, String destPath) throws Exception {
        encode(content, null, destPath, false);
    }
   /**
    * user: Rex date: 2016年12月29日 上午12:38:02
    *
    * @param content
    *            二维码内容
    * @param output
    *            输出流
    * @throws Exception
    *             void TODO 生成不带Logo的二维码,并输出到指定的输出流
    */
   public void encode(String content, OutputStream output) throws Exception {
      encode(content, null, output, false);
   }
    public InputStream encode(String content) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        encode(content, null, out, false);
        return new ByteArrayInputStream(out.toByteArray());
    }
   /**
    * user: Rex date: 2016年12月29日 上午12:39:10
    *
    * @param file
    *            二维码
    * @return 返回解析得到的二维码内容
    * @throws Exception
    *             String TODO 二维码解析
    */
   public 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<DecodeHintType, Object>();
      hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
      result = new MultiFormatReader().decode(bitmap, hints);
      String resultStr = result.getText();
      return resultStr;
   }
   /**
    * user: Rex date: 2016年12月29日 上午12:39:48
    *
    * @param path
    *            二维码存储位置
    * @return 返回解析得到的二维码内容
    * @throws Exception
    *             String TODO 二维码解析
    */
   public String decode(String path) throws Exception {
      return decode(new File(path));
   }
    public InputStream encodeDeleteWhite(String content) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        encodeDeleteWhite(content, null, out, false);
        return new ByteArrayInputStream(out.toByteArray());
    }
    private static BitMatrix deleteWhite(BitMatrix matrix) {
    /**
     * user: Rex date: 2016年12月29日 上午12:36:58
     *
     * @param content      二维码内容
     * @param logoImgPath  Logo
     * @param output       输出流
     * @param needCompress 是否压缩Logo
     * @throws Exception void TODO 生成带Logo的二维码,并输出到指定的输出流
     */
    public void encode(String content, InputStream logoImg, OutputStream output, boolean needCompress)
            throws Exception {
        BufferedImage image = createImage(content, logoImg, needCompress);
        ImageIO.write(image, FORMAT_NAME, output);
    }
    /**
     * @param content
     * @param logoImg
     * @param output       二进制输出流
     * @param needCompress
     * @throws Exception
     */
    public void encode(String content, InputStream logoImg, ByteArrayOutputStream output, boolean needCompress)
            throws Exception {
        BufferedImage image = createImage(content, logoImg, needCompress);
        ImageIO.write(image, FORMAT_NAME, output);
    }
    /**
     * @param content
     * @param logoImg
     * @param output       二进制输出流
     * @param needCompress
     * @throws Exception
     */
    public void encodeDeleteWhite(String content, InputStream logoImg, ByteArrayOutputStream output, boolean needCompress)
            throws Exception {
        BufferedImage image = createImageDeleteWhite(content, logoImg, needCompress);
        ImageIO.write(image, FORMAT_NAME, output);
    }
    /**
     * user: Rex date: 2016年12月29日 上午12:38:02
     *
     * @param content 二维码内容
     * @param output  输出流
     * @throws Exception void TODO 生成不带Logo的二维码,并输出到指定的输出流
     */
    public void encode(String content, OutputStream output) throws Exception {
        encode(content, null, output, false);
    }
    /**
     * user: Rex date: 2016年12月29日 上午12:39:10
     *
     * @param file 二维码
     * @return 返回解析得到的二维码内容
     * @throws Exception String TODO 二维码解析
     */
    public 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<DecodeHintType, Object>();
        hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
        result = new MultiFormatReader().decode(bitmap, hints);
        String resultStr = result.getText();
        return resultStr;
    }
    /**
     * user: Rex date: 2016年12月29日 上午12:39:48
     *
     * @param path 二维码存储位置
     * @return 返回解析得到的二维码内容
     * @throws Exception String TODO 二维码解析
     */
    public String decode(String path) throws Exception {
        return decode(new File(path));
    }
    private static BitMatrix deleteWhite(BitMatrix matrix) {
        int[] rec = matrix.getEnclosingRectangle();
        int resWidth = rec[2] + 1;
        int resHeight = rec[3] + 1;
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
        resMatrix.clear();
        for (int i = 0; i < resWidth; i++) {