方法 | 注释 |
---|
createQRCodeImage | 生成二维码图片 |
decodeQRCode | 解析二维码图片 |
getResultData | 获取扫描结果数据 |
syncEncodeQRCode | 同步创建黑色前景色、白色背景色的二维码图片 |
addLogoToQRCode | 添加 Logo 到二维码图片上 |
onResult | 生成二维码结果回调 |
package dev.other;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.util.EnumMap;
import java.util.Map;
import dev.utils.LogPrintUtils;
import dev.utils.common.thread.DevThreadManager;
public final class ZXingQRCodeUtils {
private ZXingQRCodeUtils() {
}
private static final String TAG = ZXingQRCodeUtils.class.getSimpleName();
public interface QRResultCallBack {
void onResult(boolean success, Bitmap bitmap, Exception e);
}
public static void createQRCodeImage(final String content, final int size) {
createQRCodeImage(content, size, null, null);
}
public static void createQRCodeImage(final String content, final int size, final QRResultCallBack qrResultCallBack) {
createQRCodeImage(content, size, null, qrResultCallBack);
}
public static void createQRCodeImage(final String content, final int size, final Bitmap logo, final QRResultCallBack qrResultCallBack) {
DevThreadManager.getInstance(10).execute(new Runnable() {
@Override
public void run() {
try {
Bitmap qrCodeBitmap = syncEncodeQRCode(content, size);
if (logo != null) {
qrCodeBitmap = addLogoToQRCode(qrCodeBitmap, logo);
}
if (qrResultCallBack != null) {
qrResultCallBack.onResult(true, qrCodeBitmap, null);
}
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "createQRCodeImage");
if (qrResultCallBack != null) {
qrResultCallBack.onResult(false, null, e);
}
}
}
});
}
private static final Map<DecodeHintType, Object> DECODE_HINTS = new EnumMap<>(DecodeHintType.class);
public interface QRScanCallBack {
void onResult(boolean success, Result result, Exception e);
}
public static void decodeQRCode(final Bitmap bitmap, final QRScanCallBack qrScanCallBack) {
if (bitmap == null) {
if (qrScanCallBack != null) {
qrScanCallBack.onResult(false, null, new Exception("bitmap is null"));
}
return;
}
DevThreadManager.getInstance(5).execute(new Runnable() {
@Override
public void run() {
try {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
Result result = new MultiFormatReader().decode(new BinaryBitmap(new HybridBinarizer(source)), DECODE_HINTS);
if (qrScanCallBack != null) {
qrScanCallBack.onResult((result != null), result, null);
}
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "decodeQRCode");
if (qrScanCallBack != null) {
qrScanCallBack.onResult(false, null, e);
}
}
}
});
}
public static String getResultData(final Result result) {
return (result != null) ? result.getText() : null;
}
private static final Map<EncodeHintType, Object> ENCODE_HINTS = new EnumMap<>(EncodeHintType.class);
static {
ENCODE_HINTS.put(EncodeHintType.CHARACTER_SET, "utf-8");
ENCODE_HINTS.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
ENCODE_HINTS.put(EncodeHintType.MARGIN, 0);
}
public static Bitmap syncEncodeQRCode(final String content, final int size) {
return syncEncodeQRCode(content, size, Color.BLACK, Color.WHITE);
}
public static Bitmap syncEncodeQRCode(final String content, final int size, final int foregroundColor, final int backgroundColor) {
try {
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, ENCODE_HINTS);
int[] pixels = new int[size * size];
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
if (matrix.get(x, y)) {
pixels[y * size + x] = foregroundColor;
} else {
pixels[y * size + x] = backgroundColor;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, size, 0, 0, size, size);
return bitmap;
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "syncEncodeQRCode");
return null;
}
}
public static Bitmap addLogoToQRCode(final Bitmap src, final Bitmap logo) {
if (src == null || logo == null) return src;
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
int logoWidth = logo.getWidth();
int logoHeight = logo.getHeight();
float scaleFactor = srcWidth * 1.0f / 4 / 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.restore();
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "addLogoToQRCode");
bitmap = null;
}
return bitmap;
}
}