二維碼問題(一)
阿新 • • 發佈:2018-11-10
描述
Android用Zxing生中文二維碼現問號。
分析
// 生二維矩陣(編碼時指定大小,生圖後縮放會模糊致識別失敗)
BitMatrix matrix=null;
// 該法不支援生中文二維碼
matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, newsize, newsize);
解決
matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, newsize, newsize);
改
matrix = new MultiFormatWriter().encode(new String(content.getBytes("UTF-8"), "ISO-8859-1"), BarcodeFormat.QR_CODE, newsize, newsize);
工具類
package widget.zxing.encoding; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.support.v4.content.ContextCompat; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; /** * @decs: 二維碼生成 * @author: xxx * @date: 2018/3/30 20:16 * @version: v 1.0 */ public final class EncodingHandler { private static final int BLACK = 0xff000000; private static final int WHITE = 0xffffffff; public static Bitmap createQRCode(Context context, String str, int widthAndHeight, int colorRes) throws WriterException { Hashtable<EncodeHintType, String> hints = new Hashtable<>(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); BitMatrix matrix = null; try { matrix = new MultiFormatWriter().encode(new String(str.getBytes("UTF-8"), "ISO-8859-1"), BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } int width = matrix.getWidth(); int height = matrix.getHeight(); int[] pixels = new int[width * height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (matrix.get(x, y)) { pixels[y * width + x] = ContextCompat.getColor(context, colorRes); } } } Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, width, 0, 0, width, height); return bitmap; } /** * 創二維碼 * * @param content content * @param widthPix widthPix * @param heightPix heightPix * @param logoBm logoBm * @return 二維碼 */ public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm) { try { if (content == null || "".equals(content)) { return null; } // 配參 Map<EncodeHintType, Object> hints = new HashMap<>(2); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 容錯級別 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 影象資料轉換(用矩陣) 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; } catch (WriterException e) { e.printStackTrace(); } return null; } /** * 二維碼中心添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); // FIXME: 2018/8/24 升級28錯: 無法將類 Canvas中的方法 save應用到給定型別; 需要: 沒有引數 找到: int 原因: 實際引數列表和形式引數列表長度不同 /*canvas.save(Canvas.ALL_SAVE_FLAG);*/ canvas.restore(); } catch (Exception e) { bitmap = null; e.getStackTrace(); } return bitmap; } }