Home > Java > javaTutorial > body text

Use ZXing to generate QR codes in Android (supports adding logo patterns)

高洛峰
Release: 2017-01-13 11:27:06
Original
1830 people have browsed it

ZXing is an open source library from Google that can be used to generate and scan QR codes. This article introduces the first part.

First of all, the renderings:

Use ZXing to generate QR codes in Android (supports adding logo patterns)

##The official download address of various ZXing related files: https://github.com/zxing/zxing/releases

Or download it here (only the jar package used in this project, version number: 3.2.0): Link: http://pan.baidu.com/s/1pLqAR5x

1. Generate 2 QR code tool class

/**
 * 二维码生成工具类
 */
public class QRCodeUtil {
 /**
  * 生成二维码Bitmap
  *
  * @param content 内容
  * @param widthPix 图片宽度
  * @param heightPix 图片高度
  * @param logoBm 二维码中心的Logo图标(可以为null)
  * @param filePath 用于存储二维码图片的文件路径
  * @return 生成二维码及保存文件是否成功
  */
 public static boolean createQRImage(String content, int widthPix, int heightPix, Bitmap logoBm, String filePath) {
  try {
   if (content == null || "".equals(content)) {
    return false;
   }
   //配置参数
   Map<encodehinttype, object=""> hints = new HashMap<>();
   hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
   //容错级别
   hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
   //设置空白边距的宽度
//   hints.put(EncodeHintType.MARGIN, 2); //default is 4
   // 图像数据转换,使用了矩阵转换
   BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix, heightPix, hints);
   int[] pixels = new int[widthPix * heightPix];
   // 下面这里按照二维码的算法,逐个生成二维码的图片,
   // 两个for循环是图片横列扫描的结果
   for (int y = 0; y < heightPix; y++) {
    for (int x = 0; x < widthPix; x++) {
     if (bitMatrix.get(x, y)) {
      pixels[y * widthPix + x] = 0xff000000;
     } else {
      pixels[y * widthPix + x] = 0xffffffff;
     }
    }
   }
   // 生成二维码图片的格式,使用ARGB_8888
   Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
   bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);
   if (logoBm != null) {
    bitmap = addLogo(bitmap, logoBm);
   }
   //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!
   return bitmap != null && bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(filePath));
  } catch (WriterException | IOException e) {
   e.printStackTrace();
  }
  return false;
 }
 /**
  * 在二维码中间添加Logo图案
  */
 private static Bitmap addLogo(Bitmap src, Bitmap logo) {
  if (src == null) {
   return null;
  }
  if (logo == null) {
   return src;
  }
  //获取图片的宽高
  int srcWidth = src.getWidth();
  int srcHeight = src.getHeight();
  int logoWidth = logo.getWidth();
  int logoHeight = logo.getHeight();
  if (srcWidth == 0 || srcHeight == 0) {
   return null;
  }
  if (logoWidth == 0 || logoHeight == 0) {
   return src;
  }
  //logo大小为二维码整体大小的1/5
  float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
  Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
  try {
   Canvas canvas = new Canvas(bitmap);
   canvas.drawBitmap(src, 0, 0, null);
   canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
   canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);
   canvas.save(Canvas.ALL_SAVE_FLAG);
   canvas.restore();
  } catch (Exception e) {
   bitmap = null;
   e.getStackTrace();
  }
  return bitmap;
 }
}</encodehinttype,>
Copy after login

2. Use in Activity:

/**
 * 二维码生成
 */
public class MainActivity extends ActionBarActivity {
  
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  //内容
  final EditText contentET = (EditText) findViewById(R.id.create_qr_content);
  //显示二维码图片
  final ImageView imageView = (ImageView) findViewById(R.id.create_qr_iv);
  //是否添加Logo
  final CheckBox addLogoCB = (CheckBox) findViewById(R.id.create_qr_addLogo);
  Button createQrBtn = (Button) findViewById(R.id.create_qr_btn);
  
  createQrBtn.setOnClickListener(new View.OnClickListener() {
  
   @Override
   public void onClick(View v) {
    final String filePath = getFileRoot(MainActivity.this) + File.separator
      + "qr_" + System.currentTimeMillis() + ".jpg";
  
    //二维码图片较大时,生成图片、保存文件的时间可能较长,因此放在新线程中
    new Thread(new Runnable() {
     @Override
     public void run() {
      boolean success = QRCodeUtil.createQRImage(contentET.getText().toString().trim(), 800, 800,
        addLogoCB.isChecked() ? BitmapFactory.decodeResource(getResources(), R.mipmap.qr_logo) : null,
        filePath);
  
      if (success) {
       runOnUiThread(new Runnable() {
        @Override
        public void run() {
         imageView.setImageBitmap(BitmapFactory.decodeFile(filePath));
        }
       });
      }
     }
    }).start();
  
   }
  });
 }
  
 //文件存储根目录
 private String getFileRoot(Context context) {
  if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
   File external = context.getExternalFilesDir(null);
   if (external != null) {
    return external.getAbsolutePath();
   }
  }
  return context.getFilesDir().getAbsolutePath();
 }
}
Copy after login
Copy after login
/**
 * 二维码生成
 */
public class MainActivity extends ActionBarActivity {
  
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  //内容
  final EditText contentET = (EditText) findViewById(R.id.create_qr_content);
  //显示二维码图片
  final ImageView imageView = (ImageView) findViewById(R.id.create_qr_iv);
  //是否添加Logo
  final CheckBox addLogoCB = (CheckBox) findViewById(R.id.create_qr_addLogo);
  Button createQrBtn = (Button) findViewById(R.id.create_qr_btn);
  
  createQrBtn.setOnClickListener(new View.OnClickListener() {
  
   @Override
   public void onClick(View v) {
    final String filePath = getFileRoot(MainActivity.this) + File.separator
      + "qr_" + System.currentTimeMillis() + ".jpg";
  
    //二维码图片较大时,生成图片、保存文件的时间可能较长,因此放在新线程中
    new Thread(new Runnable() {
     @Override
     public void run() {
      boolean success = QRCodeUtil.createQRImage(contentET.getText().toString().trim(), 800, 800,
        addLogoCB.isChecked() ? BitmapFactory.decodeResource(getResources(), R.mipmap.qr_logo) : null,
        filePath);
  
      if (success) {
       runOnUiThread(new Runnable() {
        @Override
        public void run() {
         imageView.setImageBitmap(BitmapFactory.decodeFile(filePath));
        }
       });
      }
     }
    }).start();
  
   }
  });
 }
  
 //文件存储根目录
 private String getFileRoot(Context context) {
  if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
   File external = context.getExternalFilesDir(null);
   if (external != null) {
    return external.getAbsolutePath();
   }
  }
  return context.getFilesDir().getAbsolutePath();
 }
}
Copy after login
Copy after login

3. The image files in this project are saved in the

context.getExternalFilesDir(null)
Copy after login

directory. According to the official API documentation, starting from KitKat (Android 4.4), saving files to this directory will not require SD card read and write permissions. However, tests have shown that on Redmi Note and Meizu MX3 (both systems are android 4.4.4), permissions are indeed not required; however, on my Huawei P6 (Android 4.4.2), permissions must be declared to successfully save files. , that is, the following content must be added to the manifest:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission></uses-permission>
Copy after login

Therefore, I personally guess that the so-called permissions are not required starting from Android 4.4.4.

Now I will share with you the code for Android to generate QR code and add logo

The specific code is as follows:

@Override
public Bitmap generateBitmap(String content, int width, int height) {
 QRCodeWriter qrCodeWriter = new QRCodeWriter();
 Map<EncodeHintType, String> hints = new HashMap<>();
 hints.put(EncodeHintType.CHARACTER_SET, "utf-8");//默认
  hints.put(EncodeHintType.MARGIN, "1");//无白色边框
 try {
  BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
  int[] pixels = new int[width * height];
  for (int i = 0; i < height; i++) {
   for (int j = 0; j < width; j++) {
    if (encode.get(j, i)) {
     pixels[i * width + j] = 0x00000000;
    } else {
     pixels[i * width + j] = 0xffffffff;
    }
   }
  }
  return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.RGB_565);
 } catch (WriterException e) {
  e.printStackTrace();
 }
 return null;
}
@Override
public Bitmap addLogo(Bitmap qrBitmap, Bitmap logoBitmap) {
 int qrBitmapWidth = qrBitmap.getWidth();
 int qrBitmapHeight = qrBitmap.getHeight();
 int logoBitmapWidth = logoBitmap.getWidth();
 int logoBitmapHeight = logoBitmap.getHeight();
 Bitmap blankBitmap = Bitmap.createBitmap(qrBitmapWidth, qrBitmapHeight, Bitmap.Config.ARGB_8888);
 Canvas canvas = new Canvas(blankBitmap);
 canvas.drawBitmap(qrBitmap, 0, 0, null);
 canvas.save(Canvas.ALL_SAVE_FLAG);
 float scaleSize = 1.0f;
 while ((logoBitmapWidth / scaleSize) > (qrBitmapWidth / 3.5) || (logoBitmapHeight / scaleSize) > (qrBitmapHeight / 3.5)) {
  scaleSize *= 2;
 }
 float sx = 1.0f / scaleSize;
 canvas.scale(sx, sx, qrBitmapWidth / 2, qrBitmapHeight / 2);
 canvas.drawBitmap(logoBitmap, (qrBitmapWidth - logoBitmapWidth) / 2, (qrBitmapHeight - logoBitmapHeight) / 2, null);
 canvas.restore();
 return blankBitmap;
}
Copy after login

Okay, the code is over here, I hope Helpful for everyone!

For more related articles using ZXing to generate QR codes in Android (supports adding logo patterns), please pay attention to the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!