Search in sources :

Example 11 with BitMatrix

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;
}
Also used : BitMatrix(com.google.zxing.common.BitMatrix) ResultPoint(com.google.zxing.ResultPoint)

Example 12 with BitMatrix

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;
}
Also used : BitMatrix(com.google.zxing.common.BitMatrix)

Example 13 with BitMatrix

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;
}
Also used : BitMatrix(com.google.zxing.common.BitMatrix)

Example 14 with BitMatrix

use of com.google.zxing.common.BitMatrix in project weex-example by KalicyZhou.

the class Detector method detect.

/**
   * Detects an Aztec Code in an image.
   *
   * @param isMirror if true, image is a mirror-image of original
   * @return {@link AztecDetectorResult} encapsulating results of detecting an Aztec Code
   * @throws NotFoundException if no Aztec Code can be found
   */
public AztecDetectorResult detect(boolean isMirror) throws NotFoundException {
    // 1. Get the center of the aztec matrix
    Point pCenter = getMatrixCenter();
    // 2. Get the center points of the four diagonal points just outside the bull's eye
    //  [topRight, bottomRight, bottomLeft, topLeft]
    ResultPoint[] bullsEyeCorners = getBullsEyeCorners(pCenter);
    if (isMirror) {
        ResultPoint temp = bullsEyeCorners[0];
        bullsEyeCorners[0] = bullsEyeCorners[2];
        bullsEyeCorners[2] = temp;
    }
    // 3. Get the size of the matrix and other parameters from the bull's eye
    extractParameters(bullsEyeCorners);
    // 4. Sample the grid
    BitMatrix bits = sampleGrid(image, bullsEyeCorners[shift % 4], bullsEyeCorners[(shift + 1) % 4], bullsEyeCorners[(shift + 2) % 4], bullsEyeCorners[(shift + 3) % 4]);
    // 5. Get the corners of the matrix.
    ResultPoint[] corners = getMatrixCornerPoints(bullsEyeCorners);
    return new AztecDetectorResult(bits, corners, compact, nbDataBlocks, nbLayers);
}
Also used : ResultPoint(com.google.zxing.ResultPoint) ResultPoint(com.google.zxing.ResultPoint) BitMatrix(com.google.zxing.common.BitMatrix) AztecDetectorResult(com.google.zxing.aztec.AztecDetectorResult)

Example 15 with BitMatrix

use of com.google.zxing.common.BitMatrix in project weex-example by KalicyZhou.

the class Encoder method encode.

/**
   * Encodes the given binary content as an Aztec symbol
   * 
   * @param data input data string
   * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008,
   *                      a minimum of 23% + 3 words is recommended)
   * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers
   * @return Aztec symbol matrix with metadata
   */
public static AztecCode encode(byte[] data, int minECCPercent, int userSpecifiedLayers) {
    // High-level encode
    BitArray bits = new HighLevelEncoder(data).encode();
    // stuff bits and choose symbol size
    int eccBits = bits.getSize() * minECCPercent / 100 + 11;
    int totalSizeBits = bits.getSize() + eccBits;
    boolean compact;
    int layers;
    int totalBitsInLayer;
    int wordSize;
    BitArray stuffedBits;
    if (userSpecifiedLayers != DEFAULT_AZTEC_LAYERS) {
        compact = userSpecifiedLayers < 0;
        layers = Math.abs(userSpecifiedLayers);
        if (layers > (compact ? MAX_NB_BITS_COMPACT : MAX_NB_BITS)) {
            throw new IllegalArgumentException(String.format("Illegal value %s for layers", userSpecifiedLayers));
        }
        totalBitsInLayer = totalBitsInLayer(layers, compact);
        wordSize = WORD_SIZE[layers];
        int usableBitsInLayers = totalBitsInLayer - (totalBitsInLayer % wordSize);
        stuffedBits = stuffBits(bits, wordSize);
        if (stuffedBits.getSize() + eccBits > usableBitsInLayers) {
            throw new IllegalArgumentException("Data to large for user specified layer");
        }
        if (compact && stuffedBits.getSize() > wordSize * 64) {
            // Compact format only allows 64 data words, though C4 can hold more words than that
            throw new IllegalArgumentException("Data to large for user specified layer");
        }
    } else {
        wordSize = 0;
        stuffedBits = null;
        // is the same size, but has more data.
        for (int i = 0; ; i++) {
            if (i > MAX_NB_BITS) {
                throw new IllegalArgumentException("Data too large for an Aztec code");
            }
            compact = i <= 3;
            layers = compact ? i + 1 : i;
            totalBitsInLayer = totalBitsInLayer(layers, compact);
            if (totalSizeBits > totalBitsInLayer) {
                continue;
            }
            // wordSize has changed
            if (wordSize != WORD_SIZE[layers]) {
                wordSize = WORD_SIZE[layers];
                stuffedBits = stuffBits(bits, wordSize);
            }
            int usableBitsInLayers = totalBitsInLayer - (totalBitsInLayer % wordSize);
            if (compact && stuffedBits.getSize() > wordSize * 64) {
                // Compact format only allows 64 data words, though C4 can hold more words than that
                continue;
            }
            if (stuffedBits.getSize() + eccBits <= usableBitsInLayers) {
                break;
            }
        }
    }
    BitArray messageBits = generateCheckWords(stuffedBits, totalBitsInLayer, wordSize);
    // generate mode message
    int messageSizeInWords = stuffedBits.getSize() / wordSize;
    BitArray modeMessage = generateModeMessage(compact, layers, messageSizeInWords);
    // allocate symbol
    // not including alignment lines
    int baseMatrixSize = compact ? 11 + layers * 4 : 14 + layers * 4;
    int[] alignmentMap = new int[baseMatrixSize];
    int matrixSize;
    if (compact) {
        // no alignment marks in compact mode, alignmentMap is a no-op
        matrixSize = baseMatrixSize;
        for (int i = 0; i < alignmentMap.length; i++) {
            alignmentMap[i] = i;
        }
    } else {
        matrixSize = baseMatrixSize + 1 + 2 * ((baseMatrixSize / 2 - 1) / 15);
        int origCenter = baseMatrixSize / 2;
        int center = matrixSize / 2;
        for (int i = 0; i < origCenter; i++) {
            int newOffset = i + i / 15;
            alignmentMap[origCenter - i - 1] = center - newOffset - 1;
            alignmentMap[origCenter + i] = center + newOffset + 1;
        }
    }
    BitMatrix matrix = new BitMatrix(matrixSize);
    // draw data bits
    for (int i = 0, rowOffset = 0; i < layers; i++) {
        int rowSize = compact ? (layers - i) * 4 + 9 : (layers - i) * 4 + 12;
        for (int j = 0; j < rowSize; j++) {
            int columnOffset = j * 2;
            for (int k = 0; k < 2; k++) {
                if (messageBits.get(rowOffset + columnOffset + k)) {
                    matrix.set(alignmentMap[i * 2 + k], alignmentMap[i * 2 + j]);
                }
                if (messageBits.get(rowOffset + rowSize * 2 + columnOffset + k)) {
                    matrix.set(alignmentMap[i * 2 + j], alignmentMap[baseMatrixSize - 1 - i * 2 - k]);
                }
                if (messageBits.get(rowOffset + rowSize * 4 + columnOffset + k)) {
                    matrix.set(alignmentMap[baseMatrixSize - 1 - i * 2 - k], alignmentMap[baseMatrixSize - 1 - i * 2 - j]);
                }
                if (messageBits.get(rowOffset + rowSize * 6 + columnOffset + k)) {
                    matrix.set(alignmentMap[baseMatrixSize - 1 - i * 2 - j], alignmentMap[i * 2 + k]);
                }
            }
        }
        rowOffset += rowSize * 8;
    }
    // draw mode message
    drawModeMessage(matrix, compact, matrixSize, modeMessage);
    // draw alignment marks
    if (compact) {
        drawBullsEye(matrix, matrixSize / 2, 5);
    } else {
        drawBullsEye(matrix, matrixSize / 2, 7);
        for (int i = 0, j = 0; i < baseMatrixSize / 2 - 1; i += 15, j += 16) {
            for (int k = (matrixSize / 2) & 1; k < matrixSize; k += 2) {
                matrix.set(matrixSize / 2 - j, k);
                matrix.set(matrixSize / 2 + j, k);
                matrix.set(k, matrixSize / 2 - j);
                matrix.set(k, matrixSize / 2 + j);
            }
        }
    }
    AztecCode aztec = new AztecCode();
    aztec.setCompact(compact);
    aztec.setSize(matrixSize);
    aztec.setLayers(layers);
    aztec.setCodeWords(messageSizeInWords);
    aztec.setMatrix(matrix);
    return aztec;
}
Also used : BitArray(com.google.zxing.common.BitArray) BitMatrix(com.google.zxing.common.BitMatrix)

Aggregations

BitMatrix (com.google.zxing.common.BitMatrix)114 ResultPoint (com.google.zxing.ResultPoint)26 EncodeHintType (com.google.zxing.EncodeHintType)23 Test (org.junit.Test)20 Bitmap (android.graphics.Bitmap)15 QRCodeWriter (com.google.zxing.qrcode.QRCodeWriter)14 DecoderResult (com.google.zxing.common.DecoderResult)12 WriterException (com.google.zxing.WriterException)10 DetectorResult (com.google.zxing.common.DetectorResult)10 MultiFormatWriter (com.google.zxing.MultiFormatWriter)9 Hashtable (java.util.Hashtable)9 AztecDetectorResult (com.google.zxing.aztec.AztecDetectorResult)8 EnumMap (java.util.EnumMap)8 Result (com.google.zxing.Result)7 ArrayList (java.util.ArrayList)6 Point (com.google.zxing.aztec.detector.Detector.Point)5 SymbolShapeHint (com.google.zxing.datamatrix.encoder.SymbolShapeHint)5 NotFoundException (com.google.zxing.NotFoundException)4 BitArray (com.google.zxing.common.BitArray)4 FinderPatternInfo (com.google.zxing.qrcode.detector.FinderPatternInfo)4