PDF417 detector: try 90 and 270 rotations also (#1333)

This commit is contained in:
Dan Lenski 2020-11-09 05:29:59 -08:00 committed by GitHub
parent 515688992b
commit 20405981dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 7 deletions

View file

@ -35,10 +35,10 @@ import java.util.Arrays;
*/
public final class BitMatrix implements Cloneable {
private final int width;
private final int height;
private final int rowSize;
private final int[] bits;
private int width;
private int height;
private int rowSize;
private int[] bits;
/**
* Creates an empty square {@code BitMatrix}.
@ -294,6 +294,32 @@ public final class BitMatrix implements Cloneable {
}
}
/**
* Modifies this {@code BitMatrix} to represent the same but rotated 90 degrees counterclockwise
*/
public void rotate90() {
int newWidth = height;
int newHeight = width;
int newRowSize = (newWidth + 31) / 32;
int[] newBits = new int[newRowSize * newHeight];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int offset = y * rowSize + (x / 32);
if (((bits[offset] >>> (x & 0x1f)) & 1) != 0) {
int newY = newHeight - 1 - x;
int newX = y;
int newOffset = newY * newRowSize + (newX / 32);
newBits[newOffset] |= 1 << (newX & 0x1f);
}
}
}
width = newWidth;
height = newHeight;
rowSize = newRowSize;
bits = newBits;
}
/**
* This is useful in detecting the enclosing rectangle of a 'pure' barcode.
*

View file

@ -61,7 +61,7 @@ public final class Detector {
}
/**
* <p>Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations.</p>
* <p>Detects a PDF417 Code in an image. Checks 0, 90, 180, and 270 degree rotations.</p>
*
* @param image barcode image to decode
* @param hints optional hints to detector
@ -79,9 +79,14 @@ public final class Detector {
BitMatrix bitMatrix = image.getBlackMatrix();
List<ResultPoint[]> barcodeCoordinates = detect(multiple, bitMatrix);
if (barcodeCoordinates.isEmpty()) {
// Try 180, 270, 90 degree rotations, in that order
for (int rotate = 0; barcodeCoordinates.isEmpty() && rotate < 3; rotate++) {
bitMatrix = bitMatrix.clone();
bitMatrix.rotate180();
if (rotate != 1) {
bitMatrix.rotate180();
} else {
bitMatrix.rotate90();
}
barcodeCoordinates = detect(multiple, bitMatrix);
}
return new PDF417DetectorResult(bitMatrix, barcodeCoordinates);

View file

@ -157,6 +157,22 @@ public final class BitMatrixTestCase extends Assert {
}
}
@Test
public void testRotate90Simple() {
BitMatrix matrix = new BitMatrix(3, 3);
matrix.set(0, 0);
matrix.set(0, 1);
matrix.set(1, 2);
matrix.set(2, 1);
matrix.rotate90();
assertTrue(matrix.get(0, 2));
assertTrue(matrix.get(1, 2));
assertTrue(matrix.get(2, 1));
assertTrue(matrix.get(1, 0));
}
@Test
public void testRotate180Simple() {
BitMatrix matrix = new BitMatrix(3, 3);

View file

@ -30,7 +30,9 @@ public final class PDF417BlackBox1TestCase extends AbstractBlackBoxTestCase {
public PDF417BlackBox1TestCase() {
super("src/test/resources/blackbox/pdf417-1", new MultiFormatReader(), BarcodeFormat.PDF_417);
addTest(10, 10, 0.0f);
addTest(10, 10, 90.0f);
addTest(10, 10, 180.0f);
addTest(10, 10, 270.0f);
}
}