content: package com.clothrent.common;
  
  import com.google.zxing.*;
  import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
  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.OutputStream;
  import java.util.Hashtable;
  import java.util.Random;
  
  
  public class QRCodeUtil {
      private static final String CHARSET = "utf-8";
      private static final String FORMAT = "JPG";
      // 二维码尺寸
      private static final int QRCODE_SIZE = 400;
      // LOGO宽度
      private static final int LOGO_WIDTH = 100;
      // LOGO高度
      private static final int LOGO_HEIGHT = 100;
  
      private static BufferedImage createImage(String content, String logoPath, boolean needCompress) throws Exception {
          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 (logoPath == null || "".equals(logoPath)) {
              return image;
          }else{
              // 插入图片
              QRCodeUtil.insertImage(image, logoPath, needCompress);
          }
  //        QRCodeUtil.insertWord(image, logoPath, needCompress);
          return image;
      }
  
      /**
       * 插入LOGO
       *
       * @param source
       *            二维码图片
       * @param logoPath
       *            LOGO图片地址
       * @param needCompress
       *            是否压缩
       * @throws Exception
       */
      private static void insertImage(BufferedImage source, String logoPath, boolean needCompress) throws Exception {
          File file = new File(logoPath);
          if (!file.exists()) {
              throw new Exception("logo file not found.");
          }
          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();
      }
      /**
       * 插入LOGO-文字
       *
       * @param source
       *            二维码图片
       * @param logoPath
       *            LOGO图片地址
       * @param needCompress
       *            是否压缩
       * @throws Exception
       */
      private static void insertWord(BufferedImage source, String logoPath, boolean needCompress) throws Exception {
          File file = new File(logoPath);
          if (!file.exists()) {
              throw new Exception("logo file not found.");
          }
          String productName="这是考拉";
          //把商品名称添加上去，商品名称不要太长哦，这里最多支持两行。太长就会自动截取啦
          if (productName != null && !productName.equals("")) {
              //新的图片，把带logo的二维码下面加上文字
              BufferedImage outImage = new BufferedImage(500, 500, BufferedImage.TYPE_4BYTE_ABGR);
              Graphics2D outg = outImage.createGraphics();
              //画二维码到新的面板
              outg.drawImage(source, 0, 0, source.getWidth(), source.getHeight(), null);
              //画文字到新的面板
              outg.setColor(Color.BLACK);
              outg.setFont(new Font("宋体",Font.BOLD,30)); //字体、字型、字号
              int strWidth = outg.getFontMetrics().stringWidth(productName);
              if (strWidth > 399) {
  //                  //长度过长就截取前面部分
  //                  outg.drawString(productName, 0, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 5 ); //画文字
                  //长度过长就换行
                  String productName1 = productName.substring(0, productName.length()/2);
                  String productName2 = productName.substring(productName.length()/2, productName.length());
                  int strWidth1 = outg.getFontMetrics().stringWidth(productName1);
                  int strWidth2 = outg.getFontMetrics().stringWidth(productName2);
                  outg.drawString(productName1, 200  - strWidth1/2, source.getHeight() + (outImage.getHeight() - source.getHeight())/2 + 12 );
                  BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
                  Graphics2D outg2 = outImage2.createGraphics();
                  outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
                  outg2.setColor(Color.BLACK);
                  outg2.setFont(new Font("宋体",Font.BOLD,30)); //字体、字型、字号
                  outg2.drawString(productName2, 200  - strWidth2/2, outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight())/2 + 5 );
                  outg2.dispose();
                  outImage2.flush();
                  outImage = outImage2;
              }else {
                  outg.drawString(productName, 200  - strWidth/2 , source.getHeight() + (outImage.getHeight() - source.getHeight())/2 + 12 ); //画文字
              }
              outg.dispose();
              outImage.flush();
              source=outImage;
              source.flush();
          }
      }
  
      /**
       * 生成二维码(内嵌LOGO)
       * 二维码文件名随机，文件名可能会有重复
       *
       * @param content
       *            内容
       * @param logoPath
       *            LOGO地址
       * @param destPath
       *            存放目录
       * @param needCompress
       *            是否压缩LOGO
       * @throws Exception
       */
      public static String encode(String content, String logoPath, String destPath, boolean needCompress) throws Exception {
          BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
          mkdirs(destPath);
          String fileName = new Random().nextInt(99999999) + "." + FORMAT.toLowerCase();
          ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
          return fileName;
      }
  
      /**
       * 生成二维码(内嵌LOGO)
       * 调用者指定二维码文件名
       *
       * @param content
       *            内容
       * @param logoPath
       *            LOGO地址
       * @param destPath
       *            存放目录
       * @param fileName
       *            二维码文件名
       * @param needCompress
       *            是否压缩LOGO
       * @throws Exception
       */
      public static String encode(String content, String logoPath, String destPath, String fileName, boolean needCompress) throws Exception {
          BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
          mkdirs(destPath);
          fileName = fileName.substring(0, fileName.indexOf(".")>0?fileName.indexOf("."):fileName.length())
                  + "." + FORMAT.toLowerCase();
          ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
          return fileName;
      }
  
      /**
       * 当文件夹不存在时，mkdirs会自动创建多层目录，区别于mkdir．
       * (mkdir如果父目录不存在则会抛出异常)
       * @param destPath
       *            存放目录
       */
      public static void mkdirs(String destPath) {
          File file = new File(destPath);
          if (!file.exists() && !file.isDirectory()) {
              file.mkdirs();
          }
      }
  
      /**
       * 生成二维码(内嵌LOGO)
       *
       * @param content
       *            内容
       * @param logoPath
       *            LOGO地址
       * @param destPath
       *            存储地址
       * @throws Exception
       */
      public static String encode(String content, String logoPath, String destPath) throws Exception {
          return QRCodeUtil.encode(content, logoPath, destPath, false);
      }
  
      /**
       * 生成二维码
       *
       * @param content
       *            内容
       * @param destPath
       *            存储地址
       * @param needCompress
       *            是否压缩LOGO
       * @throws Exception
       */
      public static String encode(String content, String destPath, boolean needCompress) throws Exception {
          return QRCodeUtil.encode(content, null, destPath, needCompress);
      }
  
      /**
       * 生成二维码
       *
       * @param content
       *            内容
       * @param destPath
       *            存储地址
       * @throws Exception
       */
      public static String encode(String content, String destPath) throws Exception {
          return QRCodeUtil.encode(content, null, destPath, false);
      }
  
      /**
       * 生成二维码(内嵌LOGO)
       *
       * @param content
       *            内容
       * @param logoPath
       *            LOGO地址
       * @param output
       *            输出流
       * @param needCompress
       *            是否压缩LOGO
       * @throws Exception
       */
      public static void encode(String content, String logoPath, OutputStream output, boolean needCompress)
              throws Exception {
          BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
          ImageIO.write(image, FORMAT, output);
      }
  
      /**
       * 生成二维码
       *
       * @param content
       *            内容
       * @param output
       *            输出流
       * @throws Exception
       */
      public static void encode(String content, OutputStream output) throws Exception {
          QRCodeUtil.encode(content, null, output, false);
      }
  
      /**
       * 解析二维码
       *
       * @param file
       *            二维码图片
       * @return
       * @throws Exception
       */
      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<DecodeHintType, Object>();
          hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
          result = new MultiFormatReader().decode(bitmap, hints);
          String resultStr = result.getText();
          return resultStr;
      }
  
      /**
       * 解析二维码
       *
       * @param path
       *            二维码图片地址
       * @return
       * @throws Exception
       */
      public static String decode(String path) throws Exception {
          return QRCodeUtil.decode(new File(path));
      }
  
      public static void main(String[] args) throws Exception {
          String text = "嘿嘿嘿嘿";
          //不含Logo
  //        QRCodeUtil.encode(text, null, "e:\\img", false);
          //含Logo，不指定二维码图片名
          //QRCodeUtil.encode(text, "E:\\img\\Koala.jpg", "e:\\img", true);
          //含Logo，指定二维码图片名
          String fileName = QRCodeUtil.encode(text, "E:\\img\\Koala.jpg", "e:\\img", "qrcode", true);
          System.out.println("二维码生成信息 ： "+fileName);
  //        QRCodeUtil.encode(content, LOGOPATH, filePath);
      }
  }
  