收到一个需求,平台下发给单片机的二维码数据不是字符串,而是一堆 byte 数据,接口不能改动,Android 端需要显示这个二维码。
每个 byte 转成 8 位二进制数据,二进制的 0、1表示像素点的黑白。测试点阵是 48*48 像素,2304个点,对应 288 个byte 数据。
搜了一下没找到现成轮子,想着难度也不大,参考 zxing 二维码的显示,顺便复习下 bitmap 知识,搞定。不多说,上代码
//测试数据
String data = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80000000FFFFBF9E0EFEFFFFA098D682FFFFAEAD4CBAFFFFAEA4F2BAFFFFAE8444BAFFFFA084A282FFFFBFAAAAFEFFFF80179A00FFFF86D72218FFFF925EBB16FFFFB7926380FFFFA304C056FFFFAD9623DEFFFF88246160FFFF92E96B1AFFFFAE57735AFFFFBB9F8606FFFFB60178AAFFFFB4D69F42FFFFBD2B6A52FFFFB5E533FCFFFF803D8A20FFFFBFAA26BEFFFFA088763EFFFFAEB0C7FCFFFFAEA90574FFFFAE853316FFFFA0892534FFFFBF9957C8FFFF80000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
private Bitmap createQRImage(ImageView imageView,String data) {
byte[] bytes = BytesUtils.hexStringToBytes(data);
//原始数据是 48*48 的点阵
int QR_SIZE=48;
//实际图像大小是原始数据的几倍
int MULTIPLE=2;
int QR_WIDTH=QR_SIZE*MULTIPLE;
int QR_HEIGHT=QR_SIZE*MULTIPLE;
int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
for (int y = 0; y < QR_HEIGHT; y++) {
for (int x = 0; x < QR_WIDTH; x++) {
if (getPixel(bytes, y, QR_WIDTH, x,MULTIPLE)) {
pixels[y * QR_WIDTH + x] = 0xff000000;
} else {
pixels[y * QR_HEIGHT + x] = 0xffffffff;
}
}
}
//生成二维码图片的格式,使用ARGB_8888
Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);
imageView.setImageBitmap(bitmap);
return bitmap;
}
private boolean getPixel(byte[] bytes, int y, int QR_WIDTH, int x,int multiple) {
int new_y = y / multiple;
int new_QR_WIDTH = QR_WIDTH / multiple;
int new_x = x / multiple;
int index = new_QR_WIDTH / 8 * new_y + new_x / 8;
byte tByte = bytes[index];
String bin = Integer.toBinaryString((tByte & 0xFF) + 0x100).substring(1);
String pix = bin.substring(new_x % 8, new_x % 8 + 1);
return "0".equals(pix);
}
//工具类方法
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals( "" )) {
return new byte[0];
}
// toUpperCase将字符串中的所有字符转换为大写
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
// toCharArray将此字符串转换为一个新的字符数组。
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte( hexChars[pos] ) << 4
| charToByte( hexChars[pos + 1] ));
}
return d;
}
// charToByte返回在指定字符的第一个发生的字符串中的索引,即返回匹配字符
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf( c );
}
参考:https://blog.csdn.net/Guet_Kite/article/details/74011975