use of com.google.zxing.common.BitMatrix in project weex-example by KalicyZhou.
the class QRCodeReader method extractPureBits.
/**
* This method detects a code in a "pure" image -- that is, pure monochrome image
* which contains only an unrotated, unskewed, image of a code, with some white border
* around it. This is a specialized method that works exceptionally fast in this special
* case.
*
* @see com.google.zxing.datamatrix.DataMatrixReader#extractPureBits(BitMatrix)
*/
private static BitMatrix extractPureBits(BitMatrix image) throws NotFoundException {
int[] leftTopBlack = image.getTopLeftOnBit();
int[] rightBottomBlack = image.getBottomRightOnBit();
if (leftTopBlack == null || rightBottomBlack == null) {
throw NotFoundException.getNotFoundInstance();
}
float moduleSize = moduleSize(leftTopBlack, image);
int top = leftTopBlack[1];
int bottom = rightBottomBlack[1];
int left = leftTopBlack[0];
int right = rightBottomBlack[0];
// Sanity check!
if (left >= right || top >= bottom) {
throw NotFoundException.getNotFoundInstance();
}
if (bottom - top != right - left) {
// Special case, where bottom-right module wasn't black so we found something else in the last row
// Assume it's a square, so use height as the width
right = left + (bottom - top);
}
int matrixWidth = Math.round((right - left + 1) / moduleSize);
int matrixHeight = Math.round((bottom - top + 1) / moduleSize);
if (matrixWidth <= 0 || matrixHeight <= 0) {
throw NotFoundException.getNotFoundInstance();
}
if (matrixHeight != matrixWidth) {
// Only possibly decode square regions
throw NotFoundException.getNotFoundInstance();
}
// Push in the "border" by half the module width so that we start
// sampling in the middle of the module. Just in case the image is a
// little off, this will help recover.
int nudge = (int) (moduleSize / 2.0f);
top += nudge;
left += nudge;
// But careful that this does not sample off the edge
// "right" is the farthest-right valid pixel location -- right+1 is not necessarily
// This is positive by how much the inner x loop below would be too large
int nudgedTooFarRight = left + (int) ((matrixWidth - 1) * moduleSize) - right;
if (nudgedTooFarRight > 0) {
if (nudgedTooFarRight > nudge) {
// Neither way fits; abort
throw NotFoundException.getNotFoundInstance();
}
left -= nudgedTooFarRight;
}
// See logic above
int nudgedTooFarDown = top + (int) ((matrixHeight - 1) * moduleSize) - bottom;
if (nudgedTooFarDown > 0) {
if (nudgedTooFarDown > nudge) {
// Neither way fits; abort
throw NotFoundException.getNotFoundInstance();
}
top -= nudgedTooFarDown;
}
// Now just read off the bits
BitMatrix bits = new BitMatrix(matrixWidth, matrixHeight);
for (int y = 0; y < matrixHeight; y++) {
int iOffset = top + (int) (y * moduleSize);
for (int x = 0; x < matrixWidth; x++) {
if (image.get(left + (int) (x * moduleSize), iOffset)) {
bits.set(x, y);
}
}
}
return bits;
}
use of com.google.zxing.common.BitMatrix in project weex-example by KalicyZhou.
the class PDF417Writer method bitMatrixFrombitArray.
/**
* This takes an array holding the values of the PDF 417
*
* @param input a byte array of information with 0 is black, and 1 is white
* @param margin border around the barcode
* @return BitMatrix of the input
*/
private static BitMatrix bitMatrixFrombitArray(byte[][] input, int margin) {
// Creates the bitmatrix with extra space for whitespace
BitMatrix output = new BitMatrix(input[0].length + 2 * margin, input.length + 2 * margin);
output.clear();
for (int y = 0, yOutput = output.getHeight() - margin - 1; y < input.length; y++, yOutput--) {
for (int x = 0; x < input[0].length; x++) {
// Zero is white in the bytematrix
if (input[y][x] == 1) {
output.set(x + margin, yOutput);
}
}
}
return output;
}
use of com.google.zxing.common.BitMatrix in project weex-example by KalicyZhou.
the class BitMatrixParser method readCodewords.
/**
* <p>Reads the bits in the {@link BitMatrix} representing the finder pattern in the
* correct order in order to reconstruct the codewords bytes contained within the
* QR Code.</p>
*
* @return bytes encoded within the QR Code
* @throws FormatException if the exact number of bytes expected is not read
*/
byte[] readCodewords() throws FormatException {
FormatInformation formatInfo = readFormatInformation();
Version version = readVersion();
// Get the data mask for the format used in this QR Code. This will exclude
// some bits from reading as we wind through the bit matrix.
DataMask dataMask = DataMask.forReference(formatInfo.getDataMask());
int dimension = bitMatrix.getHeight();
dataMask.unmaskBitMatrix(bitMatrix, dimension);
BitMatrix functionPattern = version.buildFunctionPattern();
boolean readingUp = true;
byte[] result = new byte[version.getTotalCodewords()];
int resultOffset = 0;
int currentByte = 0;
int bitsRead = 0;
// Read columns in pairs, from right to left
for (int j = dimension - 1; j > 0; j -= 2) {
if (j == 6) {
// Skip whole column with vertical alignment pattern;
// saves time and makes the other code proceed more cleanly
j--;
}
// Read alternatingly from bottom to top then top to bottom
for (int count = 0; count < dimension; count++) {
int i = readingUp ? dimension - 1 - count : count;
for (int col = 0; col < 2; col++) {
// Ignore bits covered by the function pattern
if (!functionPattern.get(j - col, i)) {
// Read a bit
bitsRead++;
currentByte <<= 1;
if (bitMatrix.get(j - col, i)) {
currentByte |= 1;
}
// If we've made a whole byte, save it off
if (bitsRead == 8) {
result[resultOffset++] = (byte) currentByte;
bitsRead = 0;
currentByte = 0;
}
}
}
}
// readingUp = !readingUp; // switch directions
readingUp ^= true;
}
if (resultOffset != version.getTotalCodewords()) {
throw FormatException.getFormatInstance();
}
return result;
}
use of com.google.zxing.common.BitMatrix in project weex-example by KalicyZhou.
the class FinderPatternFinder method crossCheckHorizontal.
/**
* <p>Like {@link #crossCheckVertical(int, int, int, int)}, and in fact is basically identical,
* except it reads horizontally instead of vertically. This is used to cross-cross
* check a vertical cross check and locate the real center of the alignment pattern.</p>
*/
private float crossCheckHorizontal(int startJ, int centerI, int maxCount, int originalStateCountTotal) {
BitMatrix image = this.image;
int maxJ = image.getWidth();
int[] stateCount = getCrossCheckStateCount();
int j = startJ;
while (j >= 0 && image.get(j, centerI)) {
stateCount[2]++;
j--;
}
if (j < 0) {
return Float.NaN;
}
while (j >= 0 && !image.get(j, centerI) && stateCount[1] <= maxCount) {
stateCount[1]++;
j--;
}
if (j < 0 || stateCount[1] > maxCount) {
return Float.NaN;
}
while (j >= 0 && image.get(j, centerI) && stateCount[0] <= maxCount) {
stateCount[0]++;
j--;
}
if (stateCount[0] > maxCount) {
return Float.NaN;
}
j = startJ + 1;
while (j < maxJ && image.get(j, centerI)) {
stateCount[2]++;
j++;
}
if (j == maxJ) {
return Float.NaN;
}
while (j < maxJ && !image.get(j, centerI) && stateCount[3] < maxCount) {
stateCount[3]++;
j++;
}
if (j == maxJ || stateCount[3] >= maxCount) {
return Float.NaN;
}
while (j < maxJ && image.get(j, centerI) && stateCount[4] < maxCount) {
stateCount[4]++;
j++;
}
if (stateCount[4] >= maxCount) {
return Float.NaN;
}
// If we found a finder-pattern-like section, but its size is significantly different than
// the original, assume it's a false positive
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
return Float.NaN;
}
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, j) : Float.NaN;
}
use of com.google.zxing.common.BitMatrix in project weex-example by KalicyZhou.
the class Detector method processFinderPatternInfo.
protected final DetectorResult processFinderPatternInfo(FinderPatternInfo info) throws NotFoundException, FormatException {
FinderPattern topLeft = info.getTopLeft();
FinderPattern topRight = info.getTopRight();
FinderPattern bottomLeft = info.getBottomLeft();
float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);
if (moduleSize < 1.0f) {
throw NotFoundException.getNotFoundInstance();
}
int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);
Version provisionalVersion = Version.getProvisionalVersionForDimension(dimension);
int modulesBetweenFPCenters = provisionalVersion.getDimensionForVersion() - 7;
AlignmentPattern alignmentPattern = null;
// Anything above version 1 has an alignment pattern
if (provisionalVersion.getAlignmentPatternCenters().length > 0) {
// Guess where a "bottom right" finder pattern would have been
float bottomRightX = topRight.getX() - topLeft.getX() + bottomLeft.getX();
float bottomRightY = topRight.getY() - topLeft.getY() + bottomLeft.getY();
// Estimate that alignment pattern is closer by 3 modules
// from "bottom right" to known top left location
float correctionToTopLeft = 1.0f - 3.0f / (float) modulesBetweenFPCenters;
int estAlignmentX = (int) (topLeft.getX() + correctionToTopLeft * (bottomRightX - topLeft.getX()));
int estAlignmentY = (int) (topLeft.getY() + correctionToTopLeft * (bottomRightY - topLeft.getY()));
// Kind of arbitrary -- expand search radius before giving up
for (int i = 4; i <= 16; i <<= 1) {
try {
alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float) i);
break;
} catch (NotFoundException re) {
// try next round
}
}
// If we didn't find alignment pattern... well try anyway without it
}
PerspectiveTransform transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);
BitMatrix bits = sampleGrid(image, transform, dimension);
ResultPoint[] points;
if (alignmentPattern == null) {
points = new ResultPoint[] { bottomLeft, topLeft, topRight };
} else {
points = new ResultPoint[] { bottomLeft, topLeft, topRight, alignmentPattern };
}
return new DetectorResult(bits, points);
}
Aggregations