Okay, so I'm going to take the off chance that someone here has used zxing before. I'm developing a Java application, and one of the things it needs to do is encode a byte array of data into a QR Code and then decode it at a later time.
Here's an example of what my encoder looks like:
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) { //the program shouldn't be able to get here 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) { //exit the method 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 beginning byte array in this code is just used to test it. The actual byte data will be varied.
Here's what my decoder looks like:
//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 throw new MCCDatabaseMismatchException(); } byte[] b = result.getRawBytes(); System.out.println(ByteHelper.convertUnsignedBytesToHexString(result.getText().getBytes("UTF8"))); System.out.println(ByteHelper.convertUnsignedBytesToHexString(b));
convertUnsignedBytesToHexString(byte)
is a method which converts an array of bytes in a string of hexadecimal characters.
When I try to run these two blocks of code together, this is the output:
48454c4c4f 202b0b78cc00ec11ec11ec11ec11ec11ec11ec
Clearly the text is being encoded, but the actual bytes of data are completely off. Any help would be appreciated here.
On click of button_scan_qr_code , CaptureActivity will start scanning using default camera. Once it scans any QR code, it sends back the result to onActivityResult the MainActivity . ZXing also provides online QR Code Generator. Enter the required fields, generate and scan it to get the results.
ZXing Decoder Online is a free QR-code decoder. All you have to do is provide the site with code's URL, in case it is online, or browse to its image, in case it is stored on your computer. Clicking on the Submit button will decode the image and display the text it contained.
So, for future reference for anybody who doesn't want to spend two days searching the internet to figure this out, when you encode byte arrays into QR Codes, you have to use the ISO-8859-1
character set, not UTF-8
.
this is my working example Java code to encode QR code using ZXing with UTF-8 encoding, please note: you will need to change the path and utf8 data to your path and language characters
package com.mypackage.qr; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.util.Hashtable; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.*; public class CreateQR { public static void main(String[] args) { Charset charset = Charset.forName("UTF-8"); CharsetEncoder encoder = charset.newEncoder(); byte[] b = null; try { // Convert a string to UTF-8 bytes in a ByteBuffer ByteBuffer bbuf = encoder.encode(CharBuffer.wrap("utf 8 characters - i used hebrew, but you should write some of your own language characters")); b = bbuf.array(); } catch (CharacterCodingException e) { System.out.println(e.getMessage()); } String data; try { data = new String(b, "UTF-8"); // get a byte matrix for the data BitMatrix matrix = null; int h = 100; int w = 100; com.google.zxing.Writer writer = new MultiFormatWriter(); try { Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>(2); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); matrix = writer.encode(data, com.google.zxing.BarcodeFormat.QR_CODE, w, h, hints); } catch (com.google.zxing.WriterException e) { System.out.println(e.getMessage()); } // change this path to match yours (this is my mac home folder, you can use: c:\\qr_png.png if you are on windows) String filePath = "/Users/shaybc/Desktop/OutlookQR/qr_png.png"; File file = new File(filePath); try { MatrixToImageWriter.writeToFile(matrix, "PNG", file); System.out.println("printing to " + file.getAbsolutePath()); } catch (IOException e) { System.out.println(e.getMessage()); } } catch (UnsupportedEncodingException e) { System.out.println(e.getMessage()); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With