private Pair decodePair(BitArray row, boolean right, int rowNumber, Map<DecodeHintType,?> hints) { try { int[] startEnd = findFinderPattern(row, right); FinderPattern pattern = parseFoundFinderPattern(row, rowNumber, right, startEnd); ResultPointCallback resultPointCallback = hints == null ? null : (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK); if (resultPointCallback != null) { float center = (startEnd[0] + startEnd[1]) / 2.0f; if (right) { // row is actually reversed center = row.getSize() - 1 - center; } resultPointCallback.foundPossibleResultPoint(new ResultPoint(center, rowNumber)); } DataCharacter outside = decodeDataCharacter(row, pattern, true); DataCharacter inside = decodeDataCharacter(row, pattern, false); return new Pair(1597 * outside.getValue() + inside.getValue(), outside.getChecksumPortion() + 4 * inside.getChecksumPortion(), pattern); } catch (NotFoundException ignored) { return null; } }
private int findRowSkip() { if (this.possibleCenters.size() <= 1) { return 0; } ResultPoint firstConfirmedCenter = null; for (ResultPoint center : this.possibleCenters) { if (center.getCount() >= 2) { if (firstConfirmedCenter == null) { firstConfirmedCenter = center; } else { this.hasSkipped = true; return ((int) (Math.abs(firstConfirmedCenter.getX() - center.getX()) - Math .abs(firstConfirmedCenter.getY() - center.getY()))) / 2; } } } return 0; }
/** * <p>Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations.</p> * * @param image barcode image to decode * @param hints optional hints to detector * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will * be found and returned * @return {@link PDF417DetectorResult} encapsulating results of detecting a PDF417 code * @throws NotFoundException if no PDF417 Code can be found */ public static PDF417DetectorResult detect(BinaryBitmap image, Map<DecodeHintType,?> hints, boolean multiple) throws NotFoundException { // TODO detection improvement, tryHarder could try several different luminance thresholds/blackpoints or even // different binarizers //boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER); BitMatrix bitMatrix = image.getBlackMatrix(); List<ResultPoint[]> barcodeCoordinates = detect(multiple, bitMatrix); if (barcodeCoordinates.isEmpty()) { bitMatrix = bitMatrix.clone(); bitMatrix.rotate180(); barcodeCoordinates = detect(multiple, bitMatrix); } return new PDF417DetectorResult(bitMatrix, barcodeCoordinates); }
public ViewfinderView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; density = context.getResources().getDisplayMetrics().density; Resources res = getResources(); bitmap = BitmapFactory.decodeResource(res, R.mipmap.qrcode_scan_line); // 将像素转换成dp ScreenRate = (int) (20 * density); paint = new Paint(); Resources resources = getResources(); maskColor = resources.getColor(R.color.color_black_0D); resultColor = resources.getColor(R.color.color_black_0D); resultPointColor = resources.getColor(R.color.color_yellow); possibleResultPoints = new HashSet<ResultPoint>(5); }
private static PerspectiveTransform createTransform(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, ResultPoint alignmentPattern, int dimension) { float bottomRightX; float bottomRightY; float sourceBottomRightX; float sourceBottomRightY; float dimMinusThree = ((float) dimension) - 3.5f; if (alignmentPattern != null) { bottomRightX = alignmentPattern.getX(); bottomRightY = alignmentPattern.getY(); sourceBottomRightX = dimMinusThree - IPhotoView.DEFAULT_MAX_SCALE; sourceBottomRightY = sourceBottomRightX; } else { bottomRightX = (topRight.getX() - topLeft.getX()) + bottomLeft.getX(); bottomRightY = (topRight.getY() - topLeft.getY()) + bottomLeft.getY(); sourceBottomRightX = dimMinusThree; sourceBottomRightY = dimMinusThree; } return PerspectiveTransform.quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX, sourceBottomRightY, 3.5f, dimMinusThree, topLeft.getX(), topLeft.getY(), topRight.getX(), topRight.getY(), bottomRightX, bottomRightY, bottomLeft.getX(), bottomLeft.getY()); }
private static Result[] decode(BinaryBitmap image, Map<DecodeHintType, ?> hints, boolean multiple) throws NotFoundException, FormatException, ChecksumException { List<Result> results = new ArrayList<>(); PDF417DetectorResult detectorResult = Detector.detect(image, hints, multiple); for (ResultPoint[] points : detectorResult.getPoints()) { DecoderResult decoderResult = PDF417ScanningDecoder.decode(detectorResult.getBits(), points[4], points[5], points[6], points[7], getMinCodewordWidth(points), getMaxCodewordWidth(points)); Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.PDF_417); result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.getECLevel()); PDF417ResultMetadata pdf417ResultMetadata = (PDF417ResultMetadata) decoderResult.getOther(); if (pdf417ResultMetadata != null) { result.putMetadata(ResultMetadataType.PDF417_EXTRA_METADATA, pdf417ResultMetadata); } results.add(result); } return results.toArray(new Result[results.size()]); }
Result decodeRow(int rowNumber, BitArray row, int[] extensionStartRange) throws NotFoundException { StringBuilder result = decodeRowStringBuffer; result.setLength(0); int end = decodeMiddle(row, extensionStartRange, result); String resultString = result.toString(); Map<ResultMetadataType,Object> extensionData = parseExtensionString(resultString); Result extensionResult = new Result(resultString, null, new ResultPoint[] { new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0f, rowNumber), new ResultPoint(end, rowNumber), }, BarcodeFormat.UPC_EAN_EXTENSION); if (extensionData != null) { extensionResult.putAllMetadata(extensionData); } return extensionResult; }
/** * <p>Computes the dimension (number of modules on a size) of the QR Code based on the position * of the finder patterns and estimated module size.</p> */ private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, float moduleSize) throws NotFoundException { int tltrCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleSize); int tlblCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize); int dimension = ((tltrCentersDimension + tlblCentersDimension) / 2) + 7; switch (dimension & 0x03) { // mod 4 case 0: dimension++; break; // 1? do nothing case 2: dimension--; break; case 3: throw NotFoundException.getNotFoundInstance(); } return dimension; }
static Result constructResult(List<ExpandedPair> pairs) throws NotFoundException, FormatException { BitArray binary = BitArrayBuilder.buildBitArray(pairs); AbstractExpandedDecoder decoder = AbstractExpandedDecoder.createDecoder(binary); String resultingString = decoder.parseInformation(); ResultPoint[] firstPoints = pairs.get(0).getFinderPattern().getResultPoints(); ResultPoint[] lastPoints = pairs.get(pairs.size() - 1).getFinderPattern().getResultPoints(); return new Result( resultingString, null, new ResultPoint[]{firstPoints[0], firstPoints[1], lastPoints[0], lastPoints[1]}, BarcodeFormat.RSS_EXPANDED ); }
private ResultPoint[] centerEdges(ResultPoint y, ResultPoint z, ResultPoint x, ResultPoint t) { float yi = y.getX(); float yj = y.getY(); float zi = z.getX(); float zj = z.getY(); float xi = x.getX(); float xj = x.getY(); float ti = t.getX(); float tj = t.getY(); if (yi < ((float) this.width) / 2.0f) { return new ResultPoint[]{new ResultPoint(ti - 1.0f, 1.0f + tj), new ResultPoint(1.0f + zi, 1.0f + zj), new ResultPoint(xi - 1.0f, xj - 1.0f), new ResultPoint(1.0f + yi, yj - 1.0f)}; } return new ResultPoint[]{new ResultPoint(1.0f + ti, 1.0f + tj), new ResultPoint(1.0f + zi, zj - 1.0f), new ResultPoint(xi - 1.0f, 1.0f + xj), new ResultPoint(yi - 1.0f, yj - 1.0f)}; }
/** * Superimpose a line for 1D or dots for 2D to highlight the key features of the barcode. * * @param barcode A bitmap of the captured image. * @param scaleFactor amount by which thumbnail was scaled * @param rawResult The decoded results which contains the points to draw. */ private void drawResultPoints(Bitmap barcode, float scaleFactor, Result rawResult) { ResultPoint[] points = rawResult.getResultPoints(); if (points != null && points.length > 0) { Canvas canvas = new Canvas(barcode); Paint paint = new Paint(); paint.setColor(getResources().getColor(R.color.result_points)); if (points.length == 2) { paint.setStrokeWidth(4.0f); drawLine(canvas, paint, points[0], points[1], scaleFactor); } else if (points.length == 4 && (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A || rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) { // Hacky special case -- draw two lines, for the barcode and metadata drawLine(canvas, paint, points[0], points[1], scaleFactor); drawLine(canvas, paint, points[2], points[3], scaleFactor); } else { paint.setStrokeWidth(10.0f); for (ResultPoint point : points) { if (point != null) { canvas.drawPoint(scaleFactor * point.getX(), scaleFactor * point.getY(), paint); } } } } }
Result decodeRow(int rowNumber, BitArray row, int[] extensionStartRange) throws NotFoundException { StringBuilder result = decodeRowStringBuffer; result.setLength(0); int end = decodeMiddle(row, extensionStartRange, result); String resultString = result.toString(); Map<ResultMetadataType,Object> extensionData = parseExtensionString(resultString); Result extensionResult = new Result(resultString, null, new ResultPoint[] { new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0f, (float) rowNumber), new ResultPoint((float) end, (float) rowNumber), }, BarcodeFormat.UPC_EAN_EXTENSION); if (extensionData != null) { extensionResult.putAllMetadata(extensionData); } return extensionResult; }
@Override public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException, FormatException { try { return doDecode(image, hints); } catch (NotFoundException nfe) { boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER); if (tryHarder && image.isRotateSupported()) { BinaryBitmap rotatedImage = image.rotateCounterClockwise(); Result result = doDecode(rotatedImage, hints); // Record that we found it rotated 90 degrees CCW / 270 degrees CW Map<ResultMetadataType,?> metadata = result.getResultMetadata(); int orientation = 270; if (metadata != null && metadata.containsKey(ResultMetadataType.ORIENTATION)) { // But if we found it reversed in doDecode(), add in that result here: orientation = (orientation + (Integer) metadata.get(ResultMetadataType.ORIENTATION)) % 360; } result.putMetadata(ResultMetadataType.ORIENTATION, orientation); // Update result points ResultPoint[] points = result.getResultPoints(); if (points != null) { int height = rotatedImage.getHeight(); for (int i = 0; i < points.length; i++) { points[i] = new ResultPoint(height - points[i].getY() - 1, points[i].getX()); } } return result; } else { throw nfe; } } }
/** * Creates a BitMatrix by sampling the provided image. * topLeft, topRight, bottomRight, and bottomLeft are the centers of the squares on the * diagonal just outside the bull's eye. */ private BitMatrix sampleGrid(BitMatrix image, ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomRight, ResultPoint bottomLeft) throws NotFoundException { GridSampler sampler = GridSampler.getInstance(); int dimension = getDimension(); float low = dimension / 2.0f - nbCenterLayers; float high = dimension / 2.0f + nbCenterLayers; return sampler.sampleGrid(image, dimension, dimension, low, low, // topleft high, low, // topright high, high, // bottomright low, high, // bottomleft topLeft.getX(), topLeft.getY(), topRight.getX(), topRight.getY(), bottomRight.getX(), bottomRight.getY(), bottomLeft.getX(), bottomLeft.getY()); }
@Override public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException, ChecksumException, FormatException { DecoderResult decoderResult; ResultPoint[] points; if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) { BitMatrix bits = extractPureBits(image.getBlackMatrix()); decoderResult = decoder.decode(bits); points = NO_POINTS; } else { DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect(); decoderResult = decoder.decode(detectorResult.getBits()); points = detectorResult.getPoints(); } Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.DATA_MATRIX); List<byte[]> byteSegments = decoderResult.getByteSegments(); if (byteSegments != null) { result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments); } String ecLevel = decoderResult.getECLevel(); if (ecLevel != null) { result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel); } return result; }
/** * @return number of rows we could safely skip during scanning, based on the first * two finder patterns that have been located. In some cases their position will * allow us to infer that the third pattern must lie below a certain point farther * down in the image. */ private int findRowSkip() { int max = possibleCenters.size(); if (max <= 1) { return 0; } ResultPoint firstConfirmedCenter = null; for (FinderPattern center : possibleCenters) { if (center.getCount() >= CENTER_QUORUM) { if (firstConfirmedCenter == null) { firstConfirmedCenter = center; } else { // We have two confirmed centers // How far down can we skip before resuming looking for the next // pattern? In the worst case, only the difference between the // difference in the x / y coordinates of the two centers. // This is the case where you find top left last. hasSkipped = true; return (int) (Math.abs(firstConfirmedCenter.getX() - center.getX()) - Math.abs(firstConfirmedCenter.getY() - center.getY())) / 2; } } } return 0; }
private ResultPoint getBlackPointOnSegment(float aX, float aY, float bX, float bY) { int dist = MathUtils.round(MathUtils.distance(aX, aY, bX, bY)); float xStep = (bX - aX) / dist; float yStep = (bY - aY) / dist; for (int i = 0; i < dist; i++) { int x = MathUtils.round(aX + i * xStep); int y = MathUtils.round(aY + i * yStep); if (image.get(x, y)) { return new ResultPoint(x, y); } } return null; }
@Override public Result[] decodeMultiple(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException { List<Result> results = new ArrayList<>(); DetectorResult[] detectorResults = new MultiDetector(image.getBlackMatrix()).detectMulti(hints); for (DetectorResult detectorResult : detectorResults) { try { DecoderResult decoderResult = getDecoder().decode(detectorResult.getBits(), hints); ResultPoint[] points = detectorResult.getPoints(); // If the code was mirrored: swap the bottom-left and the top-right points. if (decoderResult.getOther() instanceof QRCodeDecoderMetaData) { ((QRCodeDecoderMetaData) decoderResult.getOther()).applyMirroredCorrection(points); } Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE); List<byte[]> byteSegments = decoderResult.getByteSegments(); if (byteSegments != null) { result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments); } String ecLevel = decoderResult.getECLevel(); if (ecLevel != null) { result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel); } if (decoderResult.hasStructuredAppend()) { result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE, decoderResult.getStructuredAppendSequenceNumber()); result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.getStructuredAppendParity()); } results.add(result); } catch (ReaderException re) { // ignore and continue } } if (results.isEmpty()) { return EMPTY_RESULT_ARRAY; } else { results = processStructuredAppend(results); return results.toArray(new Result[results.size()]); } }
public ViewfinderView(Context context, AttributeSet attrs) { super(context, attrs); // Initialize these once for performance rather than calling them every time in onDraw(). paint = new Paint(Paint.ANTI_ALIAS_FLAG); Resources resources = getResources(); maskColor = resources.getColor(R.color.viewfinder_mask); resultColor = resources.getColor(R.color.result_view); laserColor = resources.getColor(R.color.viewfinder_laser); resultPointColor = resources.getColor(R.color.possible_result_points); scannerAlpha = 0; possibleResultPoints = new ArrayList<ResultPoint>(5); lastPossibleResultPoints = null; }
public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType, ?> hints) throws FormatException, NotFoundException { int[] startRange = decodeStart(row); int[] endRange = decodeEnd(row); StringBuilder result = new StringBuilder(20); decodeMiddle(row, startRange[1], endRange[0], result); String resultString = result.toString(); int[] allowedLengths = null; if (hints != null) { allowedLengths = (int[]) hints.get(DecodeHintType.ALLOWED_LENGTHS); } if (allowedLengths == null) { allowedLengths = DEFAULT_ALLOWED_LENGTHS; } int length = resultString.length(); boolean lengthOK = false; int maxAllowedLength = 0; for (int allowedLength : allowedLengths) { if (length == allowedLength) { lengthOK = true; break; } if (allowedLength > maxAllowedLength) { maxAllowedLength = allowedLength; } } if (!lengthOK && length > maxAllowedLength) { lengthOK = true; } if (lengthOK) { return new Result(resultString, null, new ResultPoint[]{new ResultPoint((float) startRange[1], (float) rowNumber), new ResultPoint((float) endRange[0], (float) rowNumber)}, BarcodeFormat.ITF); } throw FormatException.getFormatInstance(); }
private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b, float scaleFactor) { if (a != null && b != null) { canvas.drawLine(scaleFactor * a.getX(), scaleFactor * a.getY(), scaleFactor * b.getX(), scaleFactor * b.getY(), paint); } }
public void addPossibleResultPoint(ResultPoint point) { List<ResultPoint> points = possibleResultPoints; synchronized (points) { points.add(point); int size = points.size(); if (size > MAX_RESULT_POINTS) { // trim it points.subList(0, size - MAX_RESULT_POINTS / 2).clear(); } } }
/** * <p>Detects a rectangular region of black and white -- mostly black -- with a region of mostly * white, in an image.</p> * * @return {@link ResultPoint}[] describing the corners of the rectangular region. The first and * last points are opposed on the diagonal, as are the second and third. The first point will be * the topmost point and the last, the bottommost. The second point will be leftmost and the * third, the rightmost * @throws NotFoundException if no Data Matrix Code can be found */ public ResultPoint[] detect() throws NotFoundException { int height = image.getHeight(); int width = image.getWidth(); int halfHeight = height / 2; int halfWidth = width / 2; int deltaY = Math.max(1, height / (MAX_MODULES * 8)); int deltaX = Math.max(1, width / (MAX_MODULES * 8)); int top = 0; int bottom = height; int left = 0; int right = width; ResultPoint pointA = findCornerFromCenter(halfWidth, 0, left, right, halfHeight, -deltaY, top, bottom, halfWidth / 2); top = (int) pointA.getY() - 1; ResultPoint pointB = findCornerFromCenter(halfWidth, -deltaX, left, right, halfHeight, 0, top, bottom, halfHeight / 2); left = (int) pointB.getX() - 1; ResultPoint pointC = findCornerFromCenter(halfWidth, deltaX, left, right, halfHeight, 0, top, bottom, halfHeight / 2); right = (int) pointC.getX() + 1; ResultPoint pointD = findCornerFromCenter(halfWidth, 0, left, right, halfHeight, deltaY, top, bottom, halfWidth / 2); bottom = (int) pointD.getY() + 1; // Go try to find point A again with better information -- might have been off at first. pointA = findCornerFromCenter(halfWidth, 0, left, right, halfHeight, -deltaY, top, bottom, halfWidth / 4); return new ResultPoint[] { pointA, pointB, pointC, pointD }; }
public ViewfinderView(Context context, AttributeSet attrs) { super(context, attrs); // Initialize these once for performance rather than calling them every time in onDraw(). paint = new Paint(); Resources resources = getResources(); maskColor = resources.getColor(R.color.viewfinder_mask); resultColor = resources.getColor(R.color.result_view); frameColor = resources.getColor(R.color.viewfinder_frame); laserColor = resources.getColor(R.color.viewfinder_laser); resultPointColor = resources.getColor(R.color.possible_result_points); scannerAlpha = 0; possibleResultPoints = new HashSet<ResultPoint>(5); }
public AztecDetectorResult(BitMatrix bits, ResultPoint[] points, boolean compact, int nbDatablocks, int nbLayers) { super(bits, points); this.compact = compact; this.nbDatablocks = nbDatablocks; this.nbLayers = nbLayers; }
@Override public final Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException, ChecksumException, FormatException { DecoderResult decoderResult; ResultPoint[] points; if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) { BitMatrix bits = extractPureBits(image.getBlackMatrix()); decoderResult = decoder.decode(bits, hints); points = NO_POINTS; } else { DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect(hints); decoderResult = decoder.decode(detectorResult.getBits(), hints); points = detectorResult.getPoints(); } // If the code was mirrored: swap the bottom-left and the top-right points. if (decoderResult.getOther() instanceof QRCodeDecoderMetaData) { ((QRCodeDecoderMetaData) decoderResult.getOther()).applyMirroredCorrection(points); } Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE); List<byte[]> byteSegments = decoderResult.getByteSegments(); if (byteSegments != null) { result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments); } String ecLevel = decoderResult.getECLevel(); if (ecLevel != null) { result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel); } if (decoderResult.hasStructuredAppend()) { result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE, decoderResult.getStructuredAppendSequenceNumber()); result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.getStructuredAppendParity()); } return result; }
BoundingBox(BitMatrix image, ResultPoint topLeft, ResultPoint bottomLeft, ResultPoint topRight, ResultPoint bottomRight) throws NotFoundException { if ((topLeft == null && topRight == null) || (bottomLeft == null && bottomRight == null) || (topLeft != null && bottomLeft == null) || (topRight != null && bottomRight == null)) { throw NotFoundException.getNotFoundInstance(); } init(image, topLeft, bottomLeft, topRight, bottomRight); }
private void init(BitMatrix image, ResultPoint topLeft, ResultPoint bottomLeft, ResultPoint topRight, ResultPoint bottomRight) { this.image = image; this.topLeft = topLeft; this.bottomLeft = bottomLeft; this.topRight = topRight; this.bottomRight = bottomRight; calculateMinMaxValues(); }
/** * Superimpose a line for 1D or dots for 2D to highlight the key features of * the barcode. * * @param barcode * A bitmap of the captured image. * @param scaleFactor * amount by which thumbnail was scaled * @param rawResult * The decoded results which contains the points to draw. */ private void drawResultPoints(Bitmap barcode, float scaleFactor, Result rawResult) { ResultPoint[] points = rawResult.getResultPoints(); if (points != null && points.length > 0) { Canvas canvas = new Canvas(barcode); Paint paint = new Paint(); paint.setColor(Color.parseColor("#c099cc00")); if (points.length == 2) { paint.setStrokeWidth(4.0f); drawLine(canvas, paint, points[0], points[1], scaleFactor); } else if (points.length == 4 && (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A || rawResult .getBarcodeFormat() == BarcodeFormat.EAN_13)) { // Hacky special case -- draw two lines, for the barcode and // metadata drawLine(canvas, paint, points[0], points[1], scaleFactor); drawLine(canvas, paint, points[2], points[3], scaleFactor); } else { paint.setStrokeWidth(10.0f); for (ResultPoint point : points) { if (point != null) { canvas.drawPoint(scaleFactor * point.getX(), scaleFactor * point.getY(), paint); } } } } }
protected final DetectorResult processFinderPatternInfo(FinderPatternInfo info) throws NotFoundException, FormatException { ResultPoint topLeft = info.getTopLeft(); ResultPoint 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; if (provisionalVersion.getAlignmentPatternCenters().length > 0) { float correctionToTopLeft = 1.0f - (IPhotoView.DEFAULT_MAX_SCALE / ((float) modulesBetweenFPCenters)); int estAlignmentX = (int) (topLeft.getX() + ((((topRight.getX() - topLeft.getX()) + bottomLeft.getX()) - topLeft.getX()) * correctionToTopLeft)); int estAlignmentY = (int) (topLeft.getY() + ((((topRight.getY() - topLeft.getY()) + bottomLeft.getY()) - topLeft.getY()) * correctionToTopLeft)); int i = 4; while (i <= 16) { try { alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float) i); break; } catch (NotFoundException e) { i <<= 1; } } } return new DetectorResult(sampleGrid(this.image, createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension), dimension), alignmentPattern == null ? new ResultPoint[]{bottomLeft, topLeft, topRight} : new ResultPoint[]{bottomLeft, topLeft, topRight, alignmentPattern}); }
public FinderPattern(int value, int[] startEnd, int start, int end, int rowNumber) { this.value = value; this.startEnd = startEnd; this.resultPoints = new ResultPoint[] { new ResultPoint(start, rowNumber), new ResultPoint(end, rowNumber), }; }
private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, float moduleSize) throws NotFoundException { int dimension = ((MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleSize) + MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize)) / 2) + 7; switch (dimension & 3) { case 0: return dimension + 1; case 2: return dimension - 1; case 3: throw NotFoundException.getNotFoundInstance(); default: return dimension; } }
/** * Apply the result points' order correction due to mirroring. * * @param points Array of points to apply mirror correction to. */ public void applyMirroredCorrection(ResultPoint[] points) { if (!mirrored || points == null || points.length < 3) { return; } ResultPoint bottomLeft = points[0]; points[0] = points[2]; points[2] = bottomLeft; // No need to 'fix' top-left and alignment pattern. }
/** * 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); }