使用 zxing 编码和解码随机字节数组 [英] Encoding and decoding random byte array with zxing

查看:16

我正在尝试使用二维码传输字节数组,因此为了测试,我决定生成一个随机字节数组,将其编码为二维码,然后对其进行解码.我使用 ISO-8859-1 将字节数组转换为字符串 s.t 它在传输时不会丢失数据:

对于编码器端:

byte []buffer = new byte[11];com.google.zxing.Writer writer = new QRCodeWriter();随机 randomGenerator = new Random();for(int i=0;i<=10;i++){buffer[i]=(byte) randomGenerator.nextInt(254);}//Log.i("time1","original: "+Arrays.toString(buffer));字符串解码=空;尝试 {解码 = 新字符串(缓冲区,"ISO-8859-1");} catch (UnsupportedEncodingException e) {//TODO 自动生成的 catch 块e.printStackTrace();}尝试 {结果=writer.encode(解码,BarcodeFormat.QR_CODE,500, 500);} catch (WriterException e1) {//TODO 自动生成的 catch 块e1.printStackTrace();}

这样我就将字节数组转换为二维码了,没有问题.但对于接收方:

LuminanceSource source = new PlanarYUVLuminanceSource(data,640,480,0,0,640,480,false);bmtobedecoded = new BinaryBitmap(new HybridBinarizer(source));Mapmp=new HashMap();mp.put(DecodeHintType.TRY_HARDER, true);尝试 {结果= qrr.decode(bmtobedecoded,mp);} catch (NotFoundException e) {Log.i("123","未找到");e.printStackTrace();} catch (ChecksumException e) {Log.i("123","校验和");e.printStackTrace();} catch (FormatException e) {Log.i("123","格式");e.printStackTrace();}

我试图解码生成的二维码,但它抛出了 NotFoundException.有人可以帮我解决这个问题吗?

更新 1:我确认解码器与普通二维码完美配合,我还添加了 DecodeHintType.try_harder 但仍然不行.

更新 2:澄清一下,以下是我在字节数组和字符串之间进行转换的操作:

Random randomGenerator = new Random();for(int i=0;i<=10;i++){buffer[i]=(byte) randomGenerator.nextInt(254);}Log.i("time1","original: "+Arrays.toString(buffer));字符串解码=空;尝试 {解码 = 新字符串(缓冲区,"ISO-8859-1");} catch (UnsupportedEncodingException e) {//TODO 自动生成的 catch 块e.printStackTrace();}Log.i("time1","编码字符串:" + 解码);位矩阵结果=空;尝试 {结果=qw.encode(解码,BarcodeFormat.QR_CODE,500, 500);} catch (WriterException e1) {//TODO 自动生成的 catch 块e1.printStackTrace();}iv.setImageBitmap(encodematrix(result));字节 [] 编码 = 空;尝试 {编码 = 解码.getBytes("ISO-8859-1");} catch (UnsupportedEncodingException e) {//TODO 自动生成的 catch 块e.printStackTrace();}Log.i("time1","结果字节数组:" + java.util.Arrays.toString(encoded));

如果你运行这个,你可以很容易地看到你最终可以得到完全相同的数组.我对此没有任何问题.

更新 3:我也尝试使用 UTF-8 对其进行编码,但会丢失数据,因此无法在编码器中使用.

更新 4:刚刚添加:

Mapmp=new HashMap();mp.put(DecodeHintType.CHARACTER_SET, "ISO-8859-1");

在解码器中,仍然抛出异常.

解决方案

尝试 PURE_BARCODE 模式作为检测提示.奇怪的是,当图像只是纯合成图像时,发现者模式的误报检测是一个更大的问题.启发式假设一张照片,它没有这些问题.在这种替代模式下,它可以利用知道它是纯图像而不是照片的优势,并且速度更快并且永远不会出错.

  • 原文

I'm trying to transfer a byte array with QR code, so for testing, I decided to generate a random byte array, encode it as QR code, then decode it. I used ISO-8859-1 to convert byte array to string s.t it does not lose data while transmission:

For encoder side:

byte []buffer = new byte[11];
com.google.zxing.Writer writer = new QRCodeWriter();
Random randomGenerator = new Random();
    for(int i=0;i<=10;i++){
        buffer[i]=(byte) randomGenerator.nextInt(254);
    }
   // Log.i("time1","original: "+Arrays.toString(buffer));
    String decoded = null;
    try {
        decoded = new String(buffer, "ISO-8859-1");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        result=writer.encode(decoded, BarcodeFormat.QR_CODE, 500, 500);
    } catch (WriterException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

In this way I have converted byte array to QR code, it has no problem. But for the receiver side:

LuminanceSource source = new PlanarYUVLuminanceSource(data,640,480,0,0,640,480,false);
bmtobedecoded = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType,Object> mp=new HashMap<DecodeHintType, Object>();

mp.put(DecodeHintType.TRY_HARDER, true);
try {
    result= qrr.decode(bmtobedecoded,mp);
} catch (NotFoundException e) {
    Log.i("123","not found");
    e.printStackTrace();
} catch (ChecksumException e) {
    Log.i("123","checksum");
    e.printStackTrace();
} catch (FormatException e) {
    Log.i("123","format");
    e.printStackTrace();
}

I tried to decode the generated QR code, but it throws out NotFoundException. Can someone help me with this issue?

Update 1: I confirmed that the decoder works perfectly with the normal QR, I also added DecodeHintType.try_harder but still no good.

Update 2: To clarify, below is what I did to convert between byte array and string:

Random randomGenerator = new Random();
for(int i=0;i<=10;i++){
    buffer[i]=(byte) randomGenerator.nextInt(254);
}
Log.i("time1","original: "+Arrays.toString(buffer));
String decoded = null;
try {
    decoded = new String(buffer, "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
Log.i("time1","encoded string:" + decoded);
BitMatrix result=null;
try {
    result=qw.encode(decoded, BarcodeFormat.QR_CODE, 500, 500);
} catch (WriterException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}
iv.setImageBitmap(encodematrix(result));
byte[] encoded = null;
try {
    encoded = decoded.getBytes("ISO-8859-1");
} catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} 
Log.i("time1","result byte array:" + java.util.Arrays.toString(encoded));

If you run this, you can easily see that you can get exactly the same array in the end. I have no problem with this.

Update 3: I also tried encoding it using UTF-8, but it loses data, so it cannot be the used in encoder.

Update 4: Just added:

Map<DecodeHintType,Object> mp=new HashMap<DecodeHintType, Object>();
mp.put(DecodeHintType.CHARACTER_SET, "ISO-8859-1");

in the decoder, still throwing out exception.

解决方案

Try PURE_BARCODE mode as a detection hint. Strangely, false positive detection of finder patterns is a much bigger problem when the image is just a pure synthetic image. The heuristics assume a photo, which doesn't have these problems. In this alternate mode it can take advantage of knowing it's a pure image and not a photo and be much faster and never get the detection wrong.