本文相關代碼:https://gitee.com/mingyueyixi/ZxingLibraryTest
網上廣泛流傳以下一段帶有bug或者說錯誤的代碼,用來生成二維碼或條形碼:
//配置參數
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
//容錯級別
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
//設置空白邊距的寬度
hints.put(EncodeHintType.MARGIN, 0); //default is 4
// 圖像數據轉換,使用了矩陣轉換
BitMatrix bitMatrix = new new MultiFormatWriter().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;
}
}
}
……
地雷在這裏埋下:
int[] pixels = new int[widthPix * heightPix];
這段代碼是不嚴謹的,極可能產生錯誤。條形碼信息存儲在BitMatrix bitMatrix 中,而根據這個bitMatrix生成的像素數組,誰告汝,一定等於汝傳進來的width???一定等於height???
在某些二維碼格式(pdf-417,data_matrix,aztec中的兩個)下不等的,是錯誤的,循環體中的bitMatrix.get(x, y)將導致數組下標越界。崩不死汝。
正確的寫法應該是這樣:
BitMatrix bitMatrix = new new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, widthPix, heightPix, hints);
// 下面這裏按照二維碼的算法,逐個生成二維碼的圖片,
// 兩個for循環是圖片橫列掃描的結果
int bitWidth = bitMatrix.getWidth();
int bitHeight = bitMatrix.getHeight();
int[] pixels = new int[bitWidth * bitHeight];
//遍歷bitmatrix,爲像素矩陣按一行行(橫列)設置像素顏色。
for (int y = 0; y < bitHeight; y++) {//遍歷一行一行像素
for (int x = 0; x < bitWidth; x++) {
if (bitMatrix.get(x, y)) {
pixels[y * bitWidth + x] = foreColor;
} else {
pixels[y * bitWidth + x] = backColor;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(bitWidth, bitHeight, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, bitWidth, 0, 0, bitWidth, bitHeight);
但是,發現,生成的DATA MATRIX 格式二維碼實在太小了,甚至看不見。而使用Bitmap.createScaleBitmap()方法,放大之後太模糊了,不能掃碼。於是得自己寫寫縮放算法來實現無模糊縮放。
解決方法,參考我的下一篇文章。