Example QR Code Binary Data
From BoofCV
Jump to navigationJump to search
As is explained below, things are a bit tricky when you encode binary data inside a QR code. This example shows you multiple ways to decode the binary data without corrupting it. Hopefully the person who created the QR Code knew what they were doing and didn't corrupt the data either...
Example Code:
Concepts:
- QR Codes
- Binaries
Relevant Examples/Tutorials:
Example Code
/**
* When dealing with binary data embedded in a QR code things do get more complicated. You will need to convert
* the string message into a byte array. By default, it's assumed that BYTE data is a text string and it will
* encode it into a string. In general the conversion to a string will not modify the data but it's not defined
* how illegal characters are encoded. To be safe you can force the encoding to be "binary".
*
* @author Peter Abeles
*/
public class ExampleQrCodeBinaryData {
public static void main( String[] args ) throws UnsupportedEncodingException {
// Let's generate some random data. In the real world this could be a zip file or similar
byte[] originalData = new byte[500];
for (int i = 0; i < originalData.length; i++) {
originalData[i] = (byte)i;
}
// Generate a marking that's encoded with this raw data
QrCode original = new QrCodeEncoder().addBytes(originalData).fixate();
var gray = new QrCodeGeneratorImage(/* pixel per module */ 5).render(original).getGray();
// Let's detect and then decode the image
var config = new ConfigQrCode();
// If you force the encoding to "binary" then you turn off auto encoding you know the bit values will not
// be modified. It's undefined how illegal values are handled in different encodings, but often still work.
config.forceEncoding = EciEncoding.BINARY;
QrCodeDetector<GrayU8> detector = FactoryFiducial.qrcode(config, GrayU8.class);
detector.process(gray);
for (QrCode qr : detector.getDetections()) {
// Only consider QR codes that are encoded with BYTE data
if (qr.mode != QrCode.Mode.BYTE)
continue;
// Convert the message from a String to byte data. This only works if the 'binary' encoding is used
byte[] data;
if (qr.byteEncoding.equals(EciEncoding.BINARY)) {
data = BoofMiscOps.castStringToByteArray(qr.message);
} else {
// If it thought the byte data was UTF-8 you need to decode with UTF-8 because a single character
// can be multiple bytes.
data = qr.message.getBytes(qr.byteEncoding);
}
// See if the data got corrupted or not
boolean perfectMatch = data.length == originalData.length;
for (int i = 0; i < data.length; i++) {
perfectMatch &= data[i] == originalData[i];
}
// Print the results
System.out.println("Encoding: '" + qr.byteEncoding + "' Matched: " + perfectMatch);
}
}
}