text: package com.example.xch.generateqrcode;
  
  import android.graphics.Bitmap;
  import android.graphics.Canvas;
  import android.graphics.Matrix;
  import android.support.annotation.Nullable;
  import android.text.TextUtils;
  
  import com.google.zxing.BarcodeFormat;
  import com.google.zxing.EncodeHintType;
  import com.google.zxing.WriterException;
  import com.google.zxing.common.BitMatrix;
  import com.google.zxing.qrcode.QRCodeWriter;
  
  import java.util.Hashtable;
  
  public class QRCodeUtil {
      /**
       *  生成自定义二维码
       *
       * @param content                字符串内容
       * @param width                  二维码宽度
       * @param height                 二维码高度
       * @param character_set          编码方式（一般使用UTF-8）
       * @param error_correction_level 容错率 L：7% M：15% Q：25% H：35%
       * @param margin                 空白边距（二维码与边框的空白区域）
       * @param color_black            黑色色块
       * @param color_white            白色色块
       * @param logoBitmap             logo图片（传null时不添加logo）
       * @param logoPercent            logo所占百分比
       * @param bitmap_black           用来代替黑色色块的图片（传null时不代替）
       * @return
       */
      public static Bitmap createQRCodeBitmap(String content, int width, int height, String character_set, String error_correction_level,
                                              String margin, int color_black, int color_white, Bitmap logoBitmap, float logoPercent, Bitmap bitmap_black) {
          // 字符串内容判空
          if (TextUtils.isEmpty(content)) {
              return null;
          }
          // 宽和高>=0
          if (width < 0 || height < 0) {
              return null;
          }
          try {
              /** 1.设置二维码相关配置,生成BitMatrix(位矩阵)对象 */
              Hashtable<EncodeHintType, String> hints = new Hashtable<>();
              // 字符转码格式设置
              if (!TextUtils.isEmpty(character_set)) {
                  hints.put(EncodeHintType.CHARACTER_SET, character_set);
              }
              // 容错率设置
              if (!TextUtils.isEmpty(error_correction_level)) {
                  hints.put(EncodeHintType.ERROR_CORRECTION, error_correction_level);
              }
              // 空白边距设置
              if (!TextUtils.isEmpty(margin)) {
                  hints.put(EncodeHintType.MARGIN, margin);
              }
              /** 2.将配置参数传入到QRCodeWriter的encode方法生成BitMatrix(位矩阵)对象 */
              BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
  
              /** 3.创建像素数组,并根据BitMatrix(位矩阵)对象为数组元素赋颜色值 */
              if (bitmap_black != null) {
                  //从当前位图按一定的比例创建一个新的位图
                  bitmap_black = Bitmap.createScaledBitmap(bitmap_black, width, height, false);
              }
              int[] pixels = new int[width * height];
              for (int y = 0; y < height; y++) {
                  for (int x = 0; x < width; x++) {
                      //bitMatrix.get(x,y)方法返回true是黑色色块，false是白色色块
                      if (bitMatrix.get(x, y)) {// 黑色色块像素设置
                          if (bitmap_black != null) {//图片不为null，则将黑色色块换为新位图的像素。
                              pixels[y * width + x] = bitmap_black.getPixel(x, y);
                          } else {
                              pixels[y * width + x] = color_black;
                          }
                      } else {
                          pixels[y * width + x] = color_white;// 白色色块像素设置
                      }
                  }
              }
  
              /** 4.创建Bitmap对象,根据像素数组设置Bitmap每个像素点的颜色值,并返回Bitmap对象 */
              Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
              bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  
              /** 5.为二维码添加logo图标 */
              if (logoBitmap != null) {
                  return addLogo(bitmap, logoBitmap, logoPercent);
              }
              return bitmap;
          } catch (WriterException e) {
              e.printStackTrace();
              return null;
          }
      }
  
      /**
       * 向二维码中间添加logo图片(图片合成)
       *
       * @param srcBitmap   原图片（生成的简单二维码图片）
       * @param logoBitmap  logo图片
       * @param logoPercent 百分比 (用于调整logo图片在原图片中的显示大小, 取值范围[0,1] )
       *                    原图片是二维码时,建议使用0.2F,百分比过大可能导致二维码扫描失败。
       * @return
       */
      @Nullable
      private static Bitmap addLogo(@Nullable Bitmap srcBitmap, @Nullable Bitmap logoBitmap, float logoPercent) {
          if (srcBitmap == null) {
              return null;
          }
          if (logoBitmap == null) {
              return srcBitmap;
          }
          //传值不合法时使用0.2F
          if (logoPercent < 0F || logoPercent > 1F) {
              logoPercent = 0.2F;
          }
  
          /** 1. 获取原图片和Logo图片各自的宽、高值 */
          int srcWidth = srcBitmap.getWidth();
          int srcHeight = srcBitmap.getHeight();
          int logoWidth = logoBitmap.getWidth();
          int logoHeight = logoBitmap.getHeight();
  
          /** 2. 计算画布缩放的宽高比 */
          float scaleWidth = srcWidth * logoPercent / logoWidth;
          float scaleHeight = srcHeight * logoPercent / logoHeight;
  
          /** 3. 使用Canvas绘制,合成图片 */
          Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
          Canvas canvas = new Canvas(bitmap);
          canvas.drawBitmap(srcBitmap, 0, 0, null);
          canvas.scale(scaleWidth, scaleHeight, srcWidth / 2, srcHeight / 2);
          canvas.drawBitmap(logoBitmap, srcWidth / 2 - logoWidth / 2, srcHeight / 2 - logoHeight / 2, null);
  
          return bitmap;
      }
  
  }
  