Re: Scanning GZip compressed QRCode

1,177 views
Skip to first unread message

Sean Owen

unread,
Jul 25, 2012, 5:48:02 AM7/25/12
to zx...@googlegroups.com
There are a number of problems with this code, though I am not sure if any of them cause the problem you see. 

Lines like this are pointless:

                        qrCodeContent = new String ("ISO-8859-1");

This does not create a string with a certain encoding. It makes a string, and then copies it, that says "ISO-8859-1", which you then throw away. 

In the part where you do need to specify an encoding, you don't, in getBytes(). You are using the platform default, which may not be ISO-8859-1, and you need that to get this hack to work.

This also does nothing:

qrCodeContent = data.getExtras().getString("QRCode_content");

There is no extra set under that name. Whatever you are reading did not come from the library.


While I think your general approach may work if fixed up, it's safest to Base-64-encode the raw bytes, and then unencode them afterwards.

Ant-1

unread,
Jul 25, 2012, 7:34:51 AM7/25/12
to zx...@googlegroups.com
Thank you Sean !

Ok so, I know what you mean concerning this line
qrCodeContent = new String ("ISO-8859-1");
It's obviously pointless right now.


You said that I don't specify the encoding in a getBytes() but I did it in the try/catch block in my OnActivityResult method
try {
qrCodeContent = DeviceMobile.decompress(qrCodeContent.getBytes("ISO-8859-1"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

Also, I don't understand what you mean by:
You are using the platform default, which may not be ISO-8859-1, and you need that to get this hack to work. 



And finally, I set an extra in my "data" variable in my QRCode scanning activity (sorry I forgot this class in my first post) :

public class QRCodeScan extends Activity {

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        IntentIntegrator integrator = new IntentIntegrator(QRCodeScan.this);
        integrator.initiateScan();
        
}
@Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent){

     IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
    
     if (result.getContents() != null){
     contents = result.getContents();
    
     Intent qrCodeIntent = new Intent();
     qrCodeIntent.putExtra("QRCode_content", contents);
     setResult(Activity.RESULT_OK,qrCodeIntent);
     finish();
     }
     else {
     setResult(RESULT_CANCELED);
     finish();
     }
    }
}

  

Sean Owen

unread,
Jul 25, 2012, 9:43:35 AM7/25/12
to zx...@googlegroups.com
The problem line is in the encoding:

gzip.write(str.getBytes());

There you are using the platform default encoding to encode, and that is probably the error.

Ant-1

unread,
Jul 26, 2012, 4:03:14 AM7/26/12
to zx...@googlegroups.com
Oh yes, sorry I forgot this line !

What I did:

gzip.write(str.getBytes("ISO-8859-1"))  combined with  decompress(qrContent.getBytes("ISO-8859-1"))

and

gzip.write(str.getBytes("UTF-8")) combiend with  decompress(qrContent.getBytes("UTF-8"))

but the two fail.

I've tried to just read the content of the compressed QRCode and it's strange because when I encode in ISO-8859-1, it displays a lot of "�" characters (which means it can't be read by my phone I think) and when I encode in UTF-8, it displays a lot of "?" characters.

Morevover, what my eclipse console displays is slightly different between my qrCodeContent variable and the QRCode Reader (the pics above was taken with an UTF-8 encoding/decoding) 


device screenshot_QRCode content via QRCode Reader.png
eclipse screenshot_compression result.png

Lachezar Dobrev

unread,
Jul 26, 2012, 4:48:04 AM7/26/12
to Ant-1, zx...@googlegroups.com
You insist on encoding a binary stream (GZIP) as text (ISO-8859-, or
UTF- does not matter). This is going to lead to data loss, as neither
encoding is able to decode-from/encode-to the full byte range, and
UTF-8 imposes limits on consecutive bytes. As such the content will be
damaged while encoding/decoding.
You should either perform a Binary QR Code generation, or encode the
binary stream using any binary-to-text conversion (HEX, Base36,
Base64).
Note that (AFAIK) the current ZXing QR Encoder does not support
generating binary QR Codes.


2012/7/26 Ant-1 <antoin...@gmail.com>:
> --
>
>
>

Sean Owen

unread,
Jul 26, 2012, 6:11:03 AM7/26/12
to zx...@googlegroups.com
Still much confusion here. UTF-8 certainly won't work as not all byte sequences are a valid encoding of a string. The ? characters are irrelevant -- just means there is no glyph in the font that can show the character. Showing a textual representation of binary data is not meaningful anyhow.

This sort of scheme isn't "supposed" to work. While I would imagine it does in Java using ISO-8859-1, and it may be that you still have some bug I'm not seeing, it is not the right way to do this.

If you want to use text, you need to Base-64 encode the compressed data first and decode it on the other end. This will work; it will increase the size as well.

If you want to really use byte[], you need to dig into the code a bit and inject your byte[] into the encoder and bypass strings entirely.

Ant-1

unread,
Jul 26, 2012, 7:24:52 AM7/26/12
to zx...@googlegroups.com
I finally used Base64 encoding/decoding and it works !!

The only disadvantage is that increases the size of the compressed data by ~1.5.

Thank you very much Sean and Lachezar. 
Reply all
Reply to author
Forward
0 new messages