This is my first attempt at using zxing and I'm having a little
trouble. In one part of my project, I have a byte array of data which
I would like to encode into a QR Code, and in another I have a byte
array which I would like to decode.
The encoder code looks something like this:
byte[] b = {0x48, 0x45, 0x4C, 0x4C, 0x4F};
//convert the byte array into a UTF-8 string
String data;
try {
data = new String(b, "UTF8");
}
catch (UnsupportedEncodingException e) {
return;
}
//get a byte matrix for the data
ByteMatrix matrix;
com.google.zxing.Writer writer = new QRCodeWriter();
try {
matrix = writer.encode(data, com.google.zxing.BarcodeFormat.QR_CODE,
width, height);
}
catch (com.google.zxing.WriterException e) {
return;
}
//generate an image from the byte matrix
int width = matrix.getWidth();
int height = matrix.getHeight();
byte[][] array = matrix.getArray();
//create buffered image to draw to
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
//iterate through the matrix and draw the pixels to the image
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int grayValue = array[y][x] & 0xff;
image.setRGB(x, y, (grayValue == 0 ? 0 : 0xFFFFFF));
}
}
//write the image to the output stream
ImageIO.write(image, "png", outputStream);
The decoder code looks like this:
//get the data from the input stream
BufferedImage image = ImageIO.read(inputStream);
//convert the image to a binary bitmap source
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
//decode the barcode
QRCodeReader reader = new QRCodeReader();
Result result;
try {
result = reader.decode(bitmap, hints);
} catch (ReaderException e) {
//the data is improperly formatted
return;
}
byte[] b = result.getRawBytes();
System.out.println(ByteHelper.convertUnsignedBytesToHexString(result.getText().getBytes("UTF8")));
System.out.println(ByteHelper.convertUnsignedBytesToHexString(b));
Both of these chunks of code are present inside separate methods. The
assignment of b to the character string hello is just used for
illustrative purposes; the byte array really needs to encode the raw
bytes. The convertUnsignedBytesToHexString method simply prints a
string with each two characters representing the hexadecimal values of
an individual byte. The output to the decode method looks like this:
48454c4c4f
202b0b78cc00ec11ec11ec11ec11ec11ec11ec
Any help would be appreciated.
Thanks,
helixed
QR codes are 'supposed' to carry text, not bytes (byte mode
notwithstanding). Sending in your bytes as UTF-8 string isn't valid in
general, since it does not necessarily encode a UTF-8 string, and is
subject to transformations when converting back to bytes within the
encoder.
As it happens, using ISO-8859-1 encoding will work for this purpose,
though it 'shouldn't' work in the abstract, because it is a single-
byte encoding.
A better solution would be to modify the encoder so you can inject
your byte array directly.
The 11ec11ec business are padding bytes that the encoder has to put in
according to the spec to fill it out.
Alternatively you could also use alphanumeric encoding instead of
numeric.