Heim  >  Artikel  >  Java  >  Verwenden Sie ZXing, um QR-Codes in Android zu generieren (unterstützt das Hinzufügen von Logomustern)

Verwenden Sie ZXing, um QR-Codes in Android zu generieren (unterstützt das Hinzufügen von Logomustern)

高洛峰
高洛峰Original
2017-01-13 11:27:061831Durchsuche

ZXing ist eine Open-Source-Bibliothek von Google, mit der QR-Codes generiert und gescannt werden können. Dieser Artikel stellt den ersten Teil vor.

Hier zunächst die Renderings:

Verwenden Sie ZXing, um QR-Codes in Android zu generieren (unterstützt das Hinzufügen von Logomustern)

Offizielle Download-Adresse für verschiedene ZXing-bezogene Dateien: https://github.com/zxing/zxing /releases

Oder laden Sie es hier herunter (nur das in diesem Projekt verwendete JAR-Paket, Versionsnummer: 3.2.0): Link: http://pan.baidu.com/s/1pLqAR5x

1. Generieren Sie 2 QR-Code-Tool-Klasse

/**
 * 二维码生成工具类
 */
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,>

2. Verwendung in Aktivität:

/**
 * 二维码生成
 */
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();
 }
}
/**
 * 二维码生成
 */
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();
 }
}

3. Die Bilddateien in diesem Projekt werden in

gespeichert
context.getExternalFilesDir(null)

Unter dem Verzeichnis. Laut der offiziellen API-Dokumentation sind ab KitKat (Android 4.4) für das Speichern von Dateien in diesem Verzeichnis keine Lese- und Schreibberechtigungen für die SD-Karte erforderlich. Tests haben jedoch gezeigt, dass auf Redmi Note und Meizu MX3 (die Systeme sind beide Android 4.4.4) tatsächlich keine Berechtigungen erforderlich sind, auf meinem Huawei P6 (Android 4.4.2) jedoch Berechtigungen deklariert werden müssen, um Dateien erfolgreich zu speichern. , das heißt, der folgende Inhalt muss dem Manifest hinzugefügt werden:

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

Daher vermute ich persönlich, dass die sogenannten Berechtigungen ab Android 4.4.4 nicht mehr erforderlich sind.

Jetzt teile ich mit Ihnen den Code für Android, um einen QR-Code zu generieren und ein Logo hinzuzufügen

Der spezifische Code lautet wie folgt:

@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;
}

Okay, der Code ist Ich hoffe, es hilft allen!

Weitere verwandte Artikel mit ZXing zum Generieren von QR-Codes in Android (unterstützt das Hinzufügen von Logomustern) finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn