Skip to content

Instantly share code, notes, and snippets.

@creswick
Created May 31, 2014 19:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creswick/17808161de1f37a94415 to your computer and use it in GitHub Desktop.
Save creswick/17808161de1f37a94415 to your computer and use it in GitHub Desktop.
Property-based Junit test to check that zxing barcodes will round-trip with PURE_BARCODE
package com.galois.qrstream.qrpipe;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.imageio.ImageIO;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.LuminanceSource;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
/**
* Property-based test to confirm that PURE_BARCODE can correctly decode any
* machine-generated qr codes.
*
* @author creswick
*
*/
@RunWith(Parameterized.class)
public class QRCodePureBarcodeRoundTripTest {
private static final int COUNT = 30;
@Parameters(name = "{0}")
public static Collection<Object[]> setup() {
List<Object[]> qrcodes = Lists.newArrayList();
long seed = System.currentTimeMillis();
Random rand = new Random(seed);
for(int i = 0; i < COUNT; i++ ){
byte[] bytes = new byte[1 + nextNatural(rand) % 768];
rand.nextBytes(bytes);
int height = 200;// + (nextNatural(rand) % 7) * 100;
int width = 200;// + (nextNatural(rand) % 7) * 100;
String data = new String(bytes, Charsets.ISO_8859_1);
qrcodes.add(new Object[] { "seed: "+ seed + ": "+i
, data, height, width
});
}
return qrcodes;
}
public static int nextNatural(Random r) {
return Math.abs(r.nextInt());
}
private static BufferedImage encodeQRCode(String data, int height, int width)
throws WriterException {
QRCodeWriter writer = new QRCodeWriter();
Map<EncodeHintType, Object> hints = Maps.newHashMap();
hints.put(EncodeHintType.CHARACTER_SET, "ISO-8859-1");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
BitMatrix bMat = writer.encode(data, BarcodeFormat.QR_CODE,
width, height, hints);
BufferedImage newCode = MatrixToImageWriter.toBufferedImage(bMat);
return newCode;
}
private static Result decodeQRcode(BufferedImage image) throws NotFoundException,
ChecksumException, FormatException {
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = Maps.newHashMap();
hints.put(DecodeHintType.CHARACTER_SET, "ISO-8859-1");
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
// decode the barcode
QRCodeReader reader = new QRCodeReader();
Result res = reader.decode(bitmap, hints);
//return getRawData(res);
return res;
}
private String expected;
private int height;
private int width;
public QRCodePureBarcodeRoundTripTest(String name, String data, int height, int width) {
super();
this.expected = data;
this.height = height;
this.width = width;
}
@Test
public void test() throws WriterException, ChecksumException, FormatException, IOException {
BufferedImage image = encodeQRCode(expected, height, width);
Result res = null;
try {
res = decodeQRcode(image);
} catch (NotFoundException e) {
String dest = saveImage(image, "not-found-");
fail("Could not locate QR Code in image: " + dest);
}
String actual = res.getText();
if ( !actual.equals(expected) ) {
String dest = saveImage(image, "failed-roundtrip-");
assertEquals("Data did not roundtrip via image: " + dest,
expected, actual);
}
}
private String saveImage(BufferedImage image, String prefix) throws IOException {
File outputFile = File.createTempFile(prefix, ".png");
ImageIO.write(image, "png", outputFile);
return outputFile.getAbsolutePath();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment