Search in sources :

Example 21 with DetectorResult

use of com.google.zxing.common.DetectorResult in project android-zxing by PearceXu.

the class MultiDetector method detectMulti.

public DetectorResult[] detectMulti(Map<DecodeHintType, ?> hints) throws NotFoundException {
    BitMatrix image = getImage();
    ResultPointCallback resultPointCallback = hints == null ? null : (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
    MultiFinderPatternFinder finder = new MultiFinderPatternFinder(image, resultPointCallback);
    FinderPatternInfo[] infos = finder.findMulti(hints);
    if (infos.length == 0) {
        throw NotFoundException.getNotFoundInstance();
    }
    List<DetectorResult> result = new ArrayList<>();
    for (FinderPatternInfo info : infos) {
        try {
            result.add(processFinderPatternInfo(info));
        } catch (ReaderException e) {
        // ignore
        }
    }
    if (result.isEmpty()) {
        return EMPTY_DETECTOR_RESULTS;
    } else {
        return result.toArray(new DetectorResult[result.size()]);
    }
}
Also used : ResultPointCallback(com.google.zxing.ResultPointCallback) ArrayList(java.util.ArrayList) DetectorResult(com.google.zxing.common.DetectorResult) BitMatrix(com.google.zxing.common.BitMatrix) FinderPatternInfo(com.google.zxing.qrcode.detector.FinderPatternInfo) ReaderException(com.google.zxing.ReaderException)

Example 22 with DetectorResult

use of com.google.zxing.common.DetectorResult in project ofbiz-framework by apache.

the class QRCodeServices method generateQRCodeImage.

/**
 * Streams QR Code to the result.
 */
public static Map<String, Object> generateQRCodeImage(DispatchContext ctx, Map<String, Object> context) {
    Locale locale = (Locale) context.get("locale");
    String message = (String) context.get("message");
    Integer width = (Integer) context.get("width");
    Integer height = (Integer) context.get("height");
    String format = (String) context.get("format");
    String encoding = (String) context.get("encoding");
    Boolean verifyOutput = (Boolean) context.get("verifyOutput");
    String logoImage = (String) context.get("logoImage");
    Integer logoImageMaxWidth = (Integer) context.get("logoImageMaxWidth");
    Integer logoImageMaxHeight = (Integer) context.get("logoImageMaxHeight");
    if (UtilValidate.isEmpty(message)) {
        return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "ParameterCannotEmpty", new Object[] { "message" }, locale));
    }
    if (width == null) {
        width = Integer.parseInt(QRCODE_DEFAULT_WIDTH);
    }
    if (width.intValue() < MIN_SIZE || width.intValue() > MAX_SIZE) {
        return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "SizeOutOfBorderError", new Object[] { "width", String.valueOf(width), String.valueOf(MIN_SIZE), String.valueOf(MAX_SIZE) }, locale));
    }
    if (height == null) {
        height = Integer.parseInt(QRCODE_DEFAULT_HEIGHT);
    }
    if (height.intValue() < MIN_SIZE || height.intValue() > MAX_SIZE) {
        return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "SizeOutOfBorderError", new Object[] { "height", String.valueOf(height), String.valueOf(MIN_SIZE), String.valueOf(MAX_SIZE) }, locale));
    }
    if (UtilValidate.isEmpty(format)) {
        format = QRCODE_DEFAULT_FORMAT;
    }
    if (!FORMATS_SUPPORTED.contains(format)) {
        return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "ErrorFormatNotSupported", new Object[] { format }, locale));
    }
    Map<EncodeHintType, Object> encodeHints = null;
    if (UtilValidate.isNotEmpty(encoding)) {
        encodeHints = new EnumMap<>(EncodeHintType.class);
        encodeHints.put(EncodeHintType.CHARACTER_SET, encoding);
    }
    try {
        BitMatrix bitMatrix = new MultiFormatWriter().encode(message, BarcodeFormat.QR_CODE, width, height, encodeHints);
        BufferedImage bufferedImage = toBufferedImage(bitMatrix, format);
        BufferedImage logoBufferedImage = null;
        if (UtilValidate.isNotEmpty(logoImage)) {
            Map<String, Object> logoImageResult;
            try {
                logoImageResult = ImageTransform.getBufferedImage(FileUtil.getFile(logoImage).getAbsolutePath(), locale);
                logoBufferedImage = (BufferedImage) logoImageResult.get("bufferedImage");
            } catch (IllegalArgumentException | IOException e) {
                Debug.logError(e, module);
            }
        }
        if (UtilValidate.isEmpty(logoBufferedImage)) {
            logoBufferedImage = defaultLogoImage;
        }
        BufferedImage newBufferedImage = null;
        if (UtilValidate.isNotEmpty(logoBufferedImage)) {
            if (UtilValidate.isNotEmpty(logoImageMaxWidth) && UtilValidate.isNotEmpty(logoImageMaxHeight) && (logoBufferedImage.getWidth() > logoImageMaxWidth.intValue() || logoBufferedImage.getHeight() > logoImageMaxHeight.intValue())) {
                Map<String, String> typeMap = new HashMap<>();
                typeMap.put("width", logoImageMaxWidth.toString());
                typeMap.put("height", logoImageMaxHeight.toString());
                Map<String, Map<String, String>> dimensionMap = new HashMap<>();
                dimensionMap.put("QRCode", typeMap);
                Map<String, Object> logoImageResult = ImageTransform.scaleImage(logoBufferedImage, (double) logoBufferedImage.getWidth(), (double) logoBufferedImage.getHeight(), dimensionMap, "QRCode", locale);
                logoBufferedImage = (BufferedImage) logoImageResult.get("bufferedImage");
            }
            BitMatrix newBitMatrix = bitMatrix.clone();
            newBufferedImage = toBufferedImage(newBitMatrix, format);
            Graphics2D graphics = newBufferedImage.createGraphics();
            graphics.drawImage(logoBufferedImage, new AffineTransformOp(AffineTransform.getTranslateInstance(1, 1), null), (newBufferedImage.getWidth() - logoBufferedImage.getWidth()) / 2, (newBufferedImage.getHeight() - logoBufferedImage.getHeight()) / 2);
            graphics.dispose();
        }
        if (UtilValidate.isNotEmpty(verifyOutput) && verifyOutput.booleanValue()) {
            Decoder decoder = new Decoder();
            Map<DecodeHintType, Object> decodeHints = new EnumMap<>(DecodeHintType.class);
            decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
            if (UtilValidate.isNotEmpty(encoding)) {
                decodeHints.put(DecodeHintType.CHARACTER_SET, encoding);
            }
            DetectorResult detectorResult = null;
            if (UtilValidate.isNotEmpty(newBufferedImage)) {
                BitMatrix newBitMatrix = createMatrixFromImage(newBufferedImage);
                DecoderResult result = null;
                try {
                    detectorResult = new Detector(newBitMatrix).detect(decodeHints);
                    result = decoder.decode(detectorResult.getBits(), decodeHints);
                } catch (ChecksumException | FormatException | NotFoundException e) {
                    Debug.logError(e, module);
                }
                if (UtilValidate.isNotEmpty(result) && !result.getText().equals(message)) {
                    detectorResult = new Detector(bitMatrix).detect(decodeHints);
                    result = decoder.decode(detectorResult.getBits(), decodeHints);
                    if (!result.getText().equals(message)) {
                        return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "GeneratedTextNotMatchOriginal", new Object[] { result.getText(), message }, locale));
                    }
                } else {
                    bufferedImage = newBufferedImage;
                }
            } else {
                detectorResult = new Detector(bitMatrix).detect(decodeHints);
                DecoderResult result = decoder.decode(detectorResult.getBits(), decodeHints);
                if (!result.getText().equals(message)) {
                    return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "GeneratedTextNotMatchOriginal", new Object[] { result.getText(), message }, locale));
                }
            }
        } else if (UtilValidate.isNotEmpty(newBufferedImage)) {
            bufferedImage = newBufferedImage;
        }
        Map<String, Object> result = ServiceUtil.returnSuccess();
        result.put("bufferedImage", bufferedImage);
        return result;
    } catch (WriterException e) {
        return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "ErrorGenerateQRCode", new Object[] { e.toString() }, locale));
    } catch (ChecksumException e) {
        return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "ErrorVerifyQRCode", new Object[] { e.toString() }, locale));
    } catch (FormatException e) {
        return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "ErrorVerifyQRCode", new Object[] { e.toString() }, locale));
    } catch (NotFoundException e) {
        return ServiceUtil.returnError(UtilProperties.getMessage("QRCodeUiLabels", "ErrorVerifyQRCode", new Object[] { e.toString() }, locale));
    }
}
Also used : Locale(java.util.Locale) HashMap(java.util.HashMap) ChecksumException(com.google.zxing.ChecksumException) NotFoundException(com.google.zxing.NotFoundException) BitMatrix(com.google.zxing.common.BitMatrix) Decoder(com.google.zxing.qrcode.decoder.Decoder) BufferedImage(java.awt.image.BufferedImage) EncodeHintType(com.google.zxing.EncodeHintType) DecoderResult(com.google.zxing.common.DecoderResult) EnumMap(java.util.EnumMap) DecodeHintType(com.google.zxing.DecodeHintType) IOException(java.io.IOException) FormatException(com.google.zxing.FormatException) Graphics2D(java.awt.Graphics2D) AffineTransformOp(java.awt.image.AffineTransformOp) Detector(com.google.zxing.qrcode.detector.Detector) MultiFormatWriter(com.google.zxing.MultiFormatWriter) DetectorResult(com.google.zxing.common.DetectorResult) HashMap(java.util.HashMap) Map(java.util.Map) EnumMap(java.util.EnumMap) WriterException(com.google.zxing.WriterException)

Example 23 with DetectorResult

use of com.google.zxing.common.DetectorResult in project incubator-weex by apache.

the class MultiDetector method detectMulti.

public DetectorResult[] detectMulti(Map<DecodeHintType, ?> hints) throws NotFoundException {
    BitMatrix image = getImage();
    ResultPointCallback resultPointCallback = hints == null ? null : (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
    MultiFinderPatternFinder finder = new MultiFinderPatternFinder(image, resultPointCallback);
    FinderPatternInfo[] infos = finder.findMulti(hints);
    if (infos.length == 0) {
        throw NotFoundException.getNotFoundInstance();
    }
    List<DetectorResult> result = new ArrayList<>();
    for (FinderPatternInfo info : infos) {
        try {
            result.add(processFinderPatternInfo(info));
        } catch (ReaderException e) {
        // ignore
        }
    }
    if (result.isEmpty()) {
        return EMPTY_DETECTOR_RESULTS;
    } else {
        return result.toArray(new DetectorResult[result.size()]);
    }
}
Also used : ResultPointCallback(com.google.zxing.ResultPointCallback) ArrayList(java.util.ArrayList) DetectorResult(com.google.zxing.common.DetectorResult) BitMatrix(com.google.zxing.common.BitMatrix) FinderPatternInfo(com.google.zxing.qrcode.detector.FinderPatternInfo) ReaderException(com.google.zxing.ReaderException)

Example 24 with DetectorResult

use of com.google.zxing.common.DetectorResult in project incubator-weex by apache.

the class Detector method detect.

/**
 * <p>Detects a Data Matrix Code in an image.</p>
 *
 * @return {@link DetectorResult} encapsulating results of detecting a Data Matrix Code
 * @throws NotFoundException if no Data Matrix Code can be found
 */
public DetectorResult detect() throws NotFoundException {
    ResultPoint[] cornerPoints = rectangleDetector.detect();
    ResultPoint pointA = cornerPoints[0];
    ResultPoint pointB = cornerPoints[1];
    ResultPoint pointC = cornerPoints[2];
    ResultPoint pointD = cornerPoints[3];
    // Point A and D are across the diagonal from one another,
    // as are B and C. Figure out which are the solid black lines
    // by counting transitions
    List<ResultPointsAndTransitions> transitions = new ArrayList<>(4);
    transitions.add(transitionsBetween(pointA, pointB));
    transitions.add(transitionsBetween(pointA, pointC));
    transitions.add(transitionsBetween(pointB, pointD));
    transitions.add(transitionsBetween(pointC, pointD));
    Collections.sort(transitions, new ResultPointsAndTransitionsComparator());
    // Sort by number of transitions. First two will be the two solid sides; last two
    // will be the two alternating black/white sides
    ResultPointsAndTransitions lSideOne = transitions.get(0);
    ResultPointsAndTransitions lSideTwo = transitions.get(1);
    // Figure out which point is their intersection by tallying up the number of times we see the
    // endpoints in the four endpoints. One will show up twice.
    Map<ResultPoint, Integer> pointCount = new HashMap<>();
    increment(pointCount, lSideOne.getFrom());
    increment(pointCount, lSideOne.getTo());
    increment(pointCount, lSideTwo.getFrom());
    increment(pointCount, lSideTwo.getTo());
    ResultPoint maybeTopLeft = null;
    ResultPoint bottomLeft = null;
    ResultPoint maybeBottomRight = null;
    for (Map.Entry<ResultPoint, Integer> entry : pointCount.entrySet()) {
        ResultPoint point = entry.getKey();
        Integer value = entry.getValue();
        if (value == 2) {
            // this is definitely the bottom left, then -- end of two L sides
            bottomLeft = point;
        } else {
            // Otherwise it's either top left or bottom right -- just assign the two arbitrarily now
            if (maybeTopLeft == null) {
                maybeTopLeft = point;
            } else {
                maybeBottomRight = point;
            }
        }
    }
    if (maybeTopLeft == null || bottomLeft == null || maybeBottomRight == null) {
        throw NotFoundException.getNotFoundInstance();
    }
    // Bottom left is correct but top left and bottom right might be switched
    ResultPoint[] corners = { maybeTopLeft, bottomLeft, maybeBottomRight };
    // Use the dot product trick to sort them out
    ResultPoint.orderBestPatterns(corners);
    // Now we know which is which:
    ResultPoint bottomRight = corners[0];
    bottomLeft = corners[1];
    ResultPoint topLeft = corners[2];
    // Which point didn't we find in relation to the "L" sides? that's the top right corner
    ResultPoint topRight;
    if (!pointCount.containsKey(pointA)) {
        topRight = pointA;
    } else if (!pointCount.containsKey(pointB)) {
        topRight = pointB;
    } else if (!pointCount.containsKey(pointC)) {
        topRight = pointC;
    } else {
        topRight = pointD;
    }
    // Next determine the dimension by tracing along the top or right side and counting black/white
    // transitions. Since we start inside a black module, we should see a number of transitions
    // equal to 1 less than the code dimension. Well, actually 2 less, because we are going to
    // end on a black module:
    // The top right point is actually the corner of a module, which is one of the two black modules
    // adjacent to the white module at the top right. Tracing to that corner from either the top left
    // or bottom right should work here.
    int dimensionTop = transitionsBetween(topLeft, topRight).getTransitions();
    int dimensionRight = transitionsBetween(bottomRight, topRight).getTransitions();
    if ((dimensionTop & 0x01) == 1) {
        // it can't be odd, so, round... up?
        dimensionTop++;
    }
    dimensionTop += 2;
    if ((dimensionRight & 0x01) == 1) {
        // it can't be odd, so, round... up?
        dimensionRight++;
    }
    dimensionRight += 2;
    BitMatrix bits;
    ResultPoint correctedTopRight;
    // rectangular if the bigger side is at least 7/4 times the other:
    if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dimensionTop) {
        // The matrix is rectangular
        correctedTopRight = correctTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight, dimensionTop, dimensionRight);
        if (correctedTopRight == null) {
            correctedTopRight = topRight;
        }
        dimensionTop = transitionsBetween(topLeft, correctedTopRight).getTransitions();
        dimensionRight = transitionsBetween(bottomRight, correctedTopRight).getTransitions();
        if ((dimensionTop & 0x01) == 1) {
            // it can't be odd, so, round... up?
            dimensionTop++;
        }
        if ((dimensionRight & 0x01) == 1) {
            // it can't be odd, so, round... up?
            dimensionRight++;
        }
        bits = sampleGrid(image, topLeft, bottomLeft, bottomRight, correctedTopRight, dimensionTop, dimensionRight);
    } else {
        // The matrix is square
        int dimension = Math.min(dimensionRight, dimensionTop);
        // correct top right point to match the white module
        correctedTopRight = correctTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension);
        if (correctedTopRight == null) {
            correctedTopRight = topRight;
        }
        // Redetermine the dimension using the corrected top right point
        int dimensionCorrected = Math.max(transitionsBetween(topLeft, correctedTopRight).getTransitions(), transitionsBetween(bottomRight, correctedTopRight).getTransitions());
        dimensionCorrected++;
        if ((dimensionCorrected & 0x01) == 1) {
            dimensionCorrected++;
        }
        bits = sampleGrid(image, topLeft, bottomLeft, bottomRight, correctedTopRight, dimensionCorrected, dimensionCorrected);
    }
    return new DetectorResult(bits, new ResultPoint[] { topLeft, bottomLeft, bottomRight, correctedTopRight });
}
Also used : ResultPoint(com.google.zxing.ResultPoint) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BitMatrix(com.google.zxing.common.BitMatrix) ResultPoint(com.google.zxing.ResultPoint) DetectorResult(com.google.zxing.common.DetectorResult) HashMap(java.util.HashMap) Map(java.util.Map)

Example 25 with DetectorResult

use of com.google.zxing.common.DetectorResult in project incubator-weex by apache.

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);
}
Also used : ResultPoint(com.google.zxing.ResultPoint) Version(com.google.zxing.qrcode.decoder.Version) PerspectiveTransform(com.google.zxing.common.PerspectiveTransform) NotFoundException(com.google.zxing.NotFoundException) DetectorResult(com.google.zxing.common.DetectorResult) BitMatrix(com.google.zxing.common.BitMatrix) ResultPoint(com.google.zxing.ResultPoint)

Aggregations

DetectorResult (com.google.zxing.common.DetectorResult)25 BitMatrix (com.google.zxing.common.BitMatrix)21 ResultPoint (com.google.zxing.ResultPoint)20 DecoderResult (com.google.zxing.common.DecoderResult)13 Result (com.google.zxing.Result)12 ArrayList (java.util.ArrayList)12 ReaderException (com.google.zxing.ReaderException)8 QRCodeDecoderMetaData (com.google.zxing.qrcode.decoder.QRCodeDecoderMetaData)8 NotFoundException (com.google.zxing.NotFoundException)5 Detector (com.google.zxing.qrcode.detector.Detector)5 HashMap (java.util.HashMap)5 Map (java.util.Map)5 ResultPointCallback (com.google.zxing.ResultPointCallback)4 PerspectiveTransform (com.google.zxing.common.PerspectiveTransform)4 Detector (com.google.zxing.datamatrix.detector.Detector)4 MultiDetector (com.google.zxing.multi.qrcode.detector.MultiDetector)4 Version (com.google.zxing.qrcode.decoder.Version)4 FinderPatternInfo (com.google.zxing.qrcode.detector.FinderPatternInfo)4 ChecksumException (com.google.zxing.ChecksumException)1 DecodeHintType (com.google.zxing.DecodeHintType)1