Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QR Code encoding and decoding using zxing

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.

like image 201
LandonSchropp Avatar asked Mar 21 '10 22:03

LandonSchropp


People also ask

Can ZXing scan QR code?

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.

How do you use a ZXing decoder?

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.


2 Answers

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-1character set, not UTF-8.

like image 87
LandonSchropp Avatar answered Oct 04 '22 11:10

LandonSchropp


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());     } }  } 
like image 28
Shaybc Avatar answered Oct 04 '22 09:10

Shaybc