/** * 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); } } } } }
/** * @param color Color of result points * @return {@link Bitmap} with result points on it, or plain bitmap, if no result points */ public Bitmap getBitmapWithResultPoints(int color) { Bitmap bitmap = getBitmap(); Bitmap barcode = bitmap; ResultPoint[] points = mResult.getResultPoints(); if (points != null && points.length > 0 && bitmap != null) { barcode = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(barcode); canvas.drawBitmap(bitmap, 0, 0, null); Paint paint = new Paint(); paint.setColor(color); if (points.length == 2) { paint.setStrokeWidth(PREVIEW_LINE_WIDTH); drawLine(canvas, paint, points[0], points[1], mScaleFactor); } else if (points.length == 4 && (mResult.getBarcodeFormat() == BarcodeFormat.UPC_A || mResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) { // Hacky special case -- draw two lines, for the barcode and metadata drawLine(canvas, paint, points[0], points[1], mScaleFactor); drawLine(canvas, paint, points[2], points[3], mScaleFactor); } else { paint.setStrokeWidth(PREVIEW_DOT_WIDTH); for (ResultPoint point : points) { if (point != null) { canvas.drawPoint(point.getX() / mScaleFactor, point.getY() / mScaleFactor, paint); } } } } return barcode; }
public void handleResult( final Result scanResult, final Bitmap thumbnailImage, final float thumbnailScaleFactor) { vibrator.vibrate(VIBRATE_DURATION); // superimpose dots to highlight the key features of the qr code final ResultPoint[] points = scanResult.getResultPoints(); if (points != null && points.length > 0) { final Paint paint = new Paint(); paint.setColor(getResources().getColor(R.color.scan_result_dots)); paint.setStrokeWidth(10.0f); final Canvas canvas = new Canvas(thumbnailImage); canvas.scale(thumbnailScaleFactor, thumbnailScaleFactor); for (final ResultPoint point : points) canvas.drawPoint(point.getX(), point.getY(), paint); } scannerView.drawResultBitmap(thumbnailImage); final Intent result = new Intent(); result.putExtra(INTENT_EXTRA_RESULT, scanResult.getText()); setResult(RESULT_OK, result); // delayed finish new Handler() .post( new Runnable() { @Override public void run() { finish(); } }); }
protected void drawResultPoints(Bitmap barcode, 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_image_border)); paint.setStrokeWidth(3.0f); paint.setStyle(Paint.Style.STROKE); Rect border = new Rect(2, 2, barcode.getWidth() - 2, barcode.getHeight() - 2); canvas.drawRect(border, paint); paint.setColor(getResources().getColor(R.color.result_points)); if (points.length == 2) { paint.setStrokeWidth(4.0f); drawLine(canvas, paint, points[0], points[1]); } 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]); drawLine(canvas, paint, points[2], points[3]); } else { paint.setStrokeWidth(10.0f); for (ResultPoint point : points) { canvas.drawPoint(point.getX(), point.getY(), paint); } } } }
/** * Estimates module size (pixels in a module) based on the Start and End finder patterns. * * @param vertices an array of vertices: vertices[0] x, y top left barcode vertices[1] x, y bottom * left barcode vertices[2] x, y top right barcode vertices[3] x, y bottom right barcode * vertices[4] x, y top left codeword area vertices[5] x, y bottom left codeword area * vertices[6] x, y top right codeword area vertices[7] x, y bottom right codeword area * @return the module size. */ private static float computeModuleWidth(ResultPoint[] vertices) { float pixels1 = ResultPoint.distance(vertices[0], vertices[4]); float pixels2 = ResultPoint.distance(vertices[1], vertices[5]); float moduleWidth1 = (pixels1 + pixels2) / (17 * 2.0f); float pixels3 = ResultPoint.distance(vertices[6], vertices[2]); float pixels4 = ResultPoint.distance(vertices[7], vertices[3]); float moduleWidth2 = (pixels3 + pixels4) / (18 * 2.0f); return (moduleWidth1 + moduleWidth2) / 2.0f; }
private static Result translateResultPoints(Result result, int xOffset, int yOffset) { ResultPoint[] oldResultPoints = result.getResultPoints(); ResultPoint[] newResultPoints = new ResultPoint[oldResultPoints.length]; for (int i = 0; i < oldResultPoints.length; i++) { ResultPoint oldPoint = oldResultPoints[i]; newResultPoints[i] = new ResultPoint(oldPoint.getX() + xOffset, oldPoint.getY() + yOffset); } return new Result( result.getText(), result.getRawBytes(), newResultPoints, result.getBarcodeFormat()); }
private static void drawLine( Canvas canvas, Paint paint, ResultPoint a, ResultPoint b, int scaleFactor) { if (a != null && b != null) { canvas.drawLine( a.getX() / scaleFactor, a.getY() / scaleFactor, b.getX() / scaleFactor, b.getY() / scaleFactor, paint); } }
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); } }
private static BitMatrix sampleGrid( BitMatrix matrix, ResultPoint topLeft, ResultPoint bottomLeft, ResultPoint topRight, ResultPoint bottomRight, int dimension) throws NotFoundException { // Note that unlike the QR Code sampler, we didn't find the center of // modules, but the // very corners. So there is no 0.5f here; 0.0f is right. GridSampler sampler = GridSampler.getInstance(); return sampler.sampleGrid( matrix, dimension, dimension, 0.0f, // p1ToX 0.0f, // p1ToY dimension, // p2ToX 0.0f, // p2ToY dimension, // p3ToX dimension, // p3ToY 0.0f, // p4ToX dimension, // p4ToY topLeft.getX(), // p1FromX topLeft.getY(), // p1FromY topRight.getX(), // p2FromX topRight.getY(), // p2FromY bottomRight.getX(), // p3FromX bottomRight.getY(), // p3FromY bottomLeft.getX(), // p4FromX bottomLeft.getY()); // p4FromY }
private static BitMatrix sampleGrid( BitMatrix image, ResultPoint topLeft, ResultPoint bottomLeft, ResultPoint bottomRight, ResultPoint topRight, int dimension) throws NotFoundException { GridSampler sampler = GridSampler.getInstance(); return sampler.sampleGrid( image, dimension, 0.5f, 0.5f, dimension - 0.5f, 0.5f, dimension - 0.5f, dimension - 0.5f, 0.5f, dimension - 0.5f, topLeft.getX(), topLeft.getY(), topRight.getX(), topRight.getY(), bottomRight.getX(), bottomRight.getY(), bottomLeft.getX(), bottomLeft.getY()); }
// L2 distance private static int distance(ResultPoint a, ResultPoint b) { return round( (float) Math.sqrt( (a.getX() - b.getX()) * (a.getX() - b.getX()) + (a.getY() - b.getY()) * (a.getY() - b.getY()))); }
/** * Transform result to surfaceView coordinates * * <p>This method is needed because coordinates are given in landscape camera coordinates. Now is * working but transform operations aren't very explained * * <p>TODO re-write this method explaining each single value * * @return a new PointF array with transformed points */ private PointF[] transformToViewCoordinates(ResultPoint[] resultPoints) { PointF[] transformedPoints = new PointF[resultPoints.length]; int index = 0; if (resultPoints != null) { float previewX = mCameraManager.getPreviewSize().x; float previewY = mCameraManager.getPreviewSize().y; float scaleX = this.getWidth() / previewY; float scaleY = this.getHeight() / previewX; for (ResultPoint point : resultPoints) { PointF tmppoint = new PointF((previewY - point.getY()) * scaleX, point.getX() * scaleY); transformedPoints[index] = tmppoint; index++; } } return transformedPoints; }
/** * Computes the dimension (number of modules in a row) of the PDF417 Code based on vertices of the * codeword area and estimated module size. * * @param topLeft of codeword area * @param topRight of codeword area * @param bottomLeft of codeword area * @param bottomRight of codeword are * @param moduleWidth estimated module size * @return the number of modules in a row. */ private static int computeDimension( ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, ResultPoint bottomRight, float moduleWidth) { int topRowDimension = round(ResultPoint.distance(topLeft, topRight) / moduleWidth); int bottomRowDimension = round(ResultPoint.distance(bottomLeft, bottomRight) / moduleWidth); return ((((topRowDimension + bottomRowDimension) >> 1) + 8) / 17) * 17; /* * int topRowDimension = round(ResultPoint.distance(topLeft, topRight)); * //moduleWidth); int bottomRowDimension = * round(ResultPoint.distance(bottomLeft, bottomRight)); // * moduleWidth); int dimension = ((topRowDimension + bottomRowDimension) * >> 1); // Round up to nearest 17 modules i.e. there are 17 modules * per codeword //int dimension = ((((topRowDimension + * bottomRowDimension) >> 1) + 8) / 17) * 17; return dimension; */ }
/** * Counts the number of black/white transitions between two points, using something like * Bresenham's algorithm. */ private ResultPointsAndTransitions transitionsBetween(ResultPoint from, ResultPoint to) { // See QR Code Detector, sizeOfBlackWhiteBlackRun() int fromX = (int) from.getX(); int fromY = (int) from.getY(); int toX = (int) to.getX(); int toY = (int) to.getY(); boolean steep = Math.abs(toY - fromY) > Math.abs(toX - fromX); if (steep) { int temp = fromX; fromX = fromY; fromY = temp; temp = toX; toX = toY; toY = temp; } int dx = Math.abs(toX - fromX); int dy = Math.abs(toY - fromY); int error = -dx >> 1; int ystep = fromY < toY ? 1 : -1; int xstep = fromX < toX ? 1 : -1; int transitions = 0; boolean inBlack = image.get(steep ? fromY : fromX, steep ? fromX : fromY); for (int x = fromX, y = fromY; x != toX; x += xstep) { boolean isBlack = image.get(steep ? y : x, steep ? x : y); if (isBlack != inBlack) { transitions++; inBlack = isBlack; } error += dy; if (error > 0) { if (y == toY) { break; } y += ystep; error -= dx; } } return new ResultPointsAndTransitions(from, to, transitions); }
@Override public void onDraw(Canvas canvas) { // 中间的扫描框,你要修改扫描框的大小,去CameraManager里面修改 frame = CameraManager.get().getFramingRect(); if (frame == null) { return; } if (!isFirst) { isFirst = true; slideBottom = START_SCAN_Y + frame.width(); } paint.setColor(resultBitmap != null ? resultColor : maskColor); // 绘制扫描区域外的阴影 drawScanArea(canvas); if (resultBitmap != null) { // Draw the opaque result bitmap over the scanning rectangle paint.setAlpha(OPAQUE); canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint); } else { // 绘制扫描区域的四角 drawArc(canvas); // 绘制中间的线,每次刷新界面,中间的线往下移动SPEEN_DISTANCE slideTop += SPEEN_DISTANCE; if (slideTop >= slideBottom) { slideTop = START_SCAN_Y; } canvas.drawRect( frame.left + MIDDLE_LINE_PADDING, slideTop - MIDDLE_LINE_WIDTH / 2, frame.right - MIDDLE_LINE_PADDING, slideTop + MIDDLE_LINE_WIDTH / 2, paint); // 画扫描框下面的字 drawText(canvas); Collection<ResultPoint> currentPossible = possibleResultPoints; Collection<ResultPoint> currentLast = lastPossibleResultPoints; if (currentPossible.isEmpty()) { lastPossibleResultPoints = null; } else { possibleResultPoints = new HashSet<ResultPoint>(5); lastPossibleResultPoints = currentPossible; paint.setAlpha(OPAQUE); paint.setColor(resultPointColor); for (ResultPoint point : currentPossible) { canvas.drawCircle(frame.left + point.getX(), START_SCAN_Y + point.getY(), 6.0f, paint); } } if (currentLast != null) { paint.setAlpha(OPAQUE / 2); paint.setColor(resultPointColor); for (ResultPoint point : currentLast) { canvas.drawCircle(frame.left + point.getX(), START_SCAN_Y + point.getY(), 3.0f, paint); } } // 只刷新扫描框的内容,其他地方不刷新 postInvalidateDelayed(ANIMATION_DELAY, frame.left, START_SCAN_Y, frame.right, slideBottom); } }
// TODO maybe we should add missing codewords to store the correct row number to make // finding row numbers for other columns easier // use row height count to make detection of invalid row numbers more reliable int adjustIncompleteIndicatorColumnRowNumbers(BarcodeMetadata barcodeMetadata) { BoundingBox boundingBox = getBoundingBox(); ResultPoint top = isLeft ? boundingBox.getTopLeft() : boundingBox.getTopRight(); ResultPoint bottom = isLeft ? boundingBox.getBottomLeft() : boundingBox.getBottomRight(); int firstRow = imageRowToCodewordIndex((int) top.getY()); int lastRow = imageRowToCodewordIndex((int) bottom.getY()); float averageRowHeight = (lastRow - firstRow) / (float) barcodeMetadata.getRowCount(); Codeword[] codewords = getCodewords(); int barcodeRow = -1; int maxRowHeight = 1; int currentRowHeight = 0; for (int codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) { if (codewords[codewordsRow] == null) { continue; } Codeword codeword = codewords[codewordsRow]; codeword.setRowNumberAsRowIndicatorColumn(); int rowDifference = codeword.getRowNumber() - barcodeRow; // TODO improve handling with case where first row indicator doesn't start with 0 if (rowDifference == 0) { currentRowHeight++; } else if (rowDifference == 1) { maxRowHeight = Math.max(maxRowHeight, currentRowHeight); currentRowHeight = 1; barcodeRow = codeword.getRowNumber(); } else if (codeword.getRowNumber() >= barcodeMetadata.getRowCount()) { codewords[codewordsRow] = null; } else { barcodeRow = codeword.getRowNumber(); currentRowHeight = 1; } } return (int) (averageRowHeight + 0.5); }
/** * 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 rawResult The decoded results which contains the points to draw. */ private void drawResultPoints(Bitmap barcode, 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_image_border)); paint.setStrokeWidth(3.0f); paint.setStyle(Paint.Style.STROKE); Rect border = new Rect(2, 2, barcode.getWidth() - 2, barcode.getHeight() - 2); canvas.drawRect(border, paint); paint.setColor(getResources().getColor(R.color.result_points)); if (points.length == 2) { paint.setStrokeWidth(4.0f); canvas.drawLine( points[0].getX(), points[0].getY(), points[1].getX(), points[1].getY(), paint); } else { paint.setStrokeWidth(10.0f); for (ResultPoint point : points) { canvas.drawPoint(point.getX(), point.getY(), paint); } } } }
private static PerspectiveTransform a(ResultPoint paramResultPoint1, ResultPoint paramResultPoint2, ResultPoint paramResultPoint3, ResultPoint paramResultPoint4, int paramInt) { float f1 = paramInt - 3.5F; float f2; float f3; float f4; float f5; if (paramResultPoint4 != null) { f2 = paramResultPoint4.a(); f3 = paramResultPoint4.b(); f4 = f1 - 3.0F; f5 = f4; } while (true) { return PerspectiveTransform.a(3.5F, 3.5F, f1, 3.5F, f5, f4, 3.5F, f1, paramResultPoint1.a(), paramResultPoint1.b(), paramResultPoint2.a(), paramResultPoint2.b(), f2, f3, paramResultPoint3.a(), paramResultPoint3.b()); f2 = paramResultPoint2.a() - paramResultPoint1.a() + paramResultPoint3.a(); f3 = paramResultPoint2.b() - paramResultPoint1.b() + paramResultPoint3.b(); f4 = f1; f5 = f1; } }
private static int a(ResultPoint paramResultPoint1, ResultPoint paramResultPoint2, ResultPoint paramResultPoint3, float paramFloat) { int i = 7 + (MathUtils.a(ResultPoint.a(paramResultPoint1, paramResultPoint2) / paramFloat) + MathUtils.a(ResultPoint.a(paramResultPoint1, paramResultPoint3) / paramFloat) >> 1); switch (i & 0x3) { case 1: default: case 0: case 2: while (true) { return i; i++; continue; i--; } case 3: } throw NotFoundException.a(); }
private ResultPoint[] centerEdges(ResultPoint resultpoint, ResultPoint resultpoint1, ResultPoint resultpoint2, ResultPoint resultpoint3) { float f = resultpoint.getX(); float f1 = resultpoint.getY(); float f2 = resultpoint1.getX(); float f3 = resultpoint1.getY(); float f4 = resultpoint2.getX(); float f5 = resultpoint2.getY(); float f6 = resultpoint3.getX(); float f7 = resultpoint3.getY(); if (f < (float)width / 2.0F) { return (new ResultPoint[] { new ResultPoint(f6 - 1.0F, 1.0F + f7), new ResultPoint(1.0F + f2, 1.0F + f3), new ResultPoint(f4 - 1.0F, f5 - 1.0F), new ResultPoint(1.0F + f, f1 - 1.0F) }); } else { return (new ResultPoint[] { new ResultPoint(1.0F + f6, 1.0F + f7), new ResultPoint(1.0F + f2, f3 - 1.0F), new ResultPoint(f4 - 1.0F, 1.0F + f5), new ResultPoint(f - 1.0F, f1 - 1.0F) }); } }
private float a(ResultPoint paramResultPoint1, ResultPoint paramResultPoint2) { float f1 = a((int)paramResultPoint1.a(), (int)paramResultPoint1.b(), (int)paramResultPoint2.a(), (int)paramResultPoint2.b()); float f2 = a((int)paramResultPoint2.a(), (int)paramResultPoint2.b(), (int)paramResultPoint1.a(), (int)paramResultPoint1.b()); float f3; if (Float.isNaN(f1)) f3 = f2 / 7.0F; while (true) { return f3; if (Float.isNaN(f2)) { f3 = f1 / 7.0F; continue; } f3 = (f1 + f2) / 14.0F; } }
/** * 绘制可疑点 * * @param canvas */ private void drawPossibleResult(Canvas canvas) { Collection<ResultPoint> currentPossible = possibleResultPoints; Collection<ResultPoint> currentLast = lastPossibleResultPoints; if (currentPossible.isEmpty()) { lastPossibleResultPoints = null; } else { possibleResultPoints = new HashSet<ResultPoint>(5); lastPossibleResultPoints = currentPossible; paint.setAlpha(OPAQUE); paint.setColor(getResultPointColor()); for (ResultPoint point : currentPossible) { canvas.drawCircle(point.getX(), point.getY(), getNewResultPointRadius(), paint); } } if (currentLast != null) { paint.setAlpha(OPAQUE / 2); paint.setColor(resultPointColor); for (ResultPoint point : currentLast) { canvas.drawCircle(point.getX(), point.getY(), getLastResultPointRadius(), paint); } } }
@Override public void onDraw(Canvas canvas) { Rect frame = CameraManager.get().getFramingRect(); if (frame == null) { return; } int width = canvas.getWidth(); int height = canvas.getHeight(); // Draw the exterior (i.e. outside the framing rect) darkened paint.setColor(resultBitmap != null ? resultColor : maskColor); canvas.drawRect(0, 0, width, frame.top, paint); canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint); canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint); canvas.drawRect(0, frame.bottom + 1, width, height, paint); if (resultBitmap != null) { // Draw the opaque result bitmap over the scanning rectangle paint.setAlpha(OPAQUE); canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint); } else { // Draw a two pixel solid black border inside the framing rect paint.setColor(frameColor); canvas.drawRect(frame.left, frame.top, frame.right + 1, frame.top + 2, paint); canvas.drawRect(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1, paint); canvas.drawRect(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1, paint); canvas.drawRect(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1, paint); // Draw a red "laser scanner" line through the middle to show decoding is active paint.setColor(laserColor); paint.setAlpha(SCANNER_ALPHA[scannerAlpha]); scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length; int middle = frame.height() / 2 + frame.top; canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint); Collection<ResultPoint> currentPossible = possibleResultPoints; Collection<ResultPoint> currentLast = lastPossibleResultPoints; if (currentPossible.isEmpty()) { lastPossibleResultPoints = null; } else { possibleResultPoints = new HashSet<ResultPoint>(5); lastPossibleResultPoints = currentPossible; paint.setAlpha(OPAQUE); paint.setColor(resultPointColor); for (ResultPoint point : currentPossible) { canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint); } } if (currentLast != null) { paint.setAlpha(OPAQUE / 2); paint.setColor(resultPointColor); for (ResultPoint point : currentLast) { canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 3.0f, paint); } } // Request another update at the animation interval, but only repaint the laser line, // not the entire viewfinder mask. postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom); } }
final FinderPatternInfo find(Map<DecodeHintType, ?> paramMap) throws NotFoundException { int i; int j; int k; int m; boolean bool; int[] arrayOfInt; int n; if ((paramMap != null) && (paramMap.containsKey(DecodeHintType.TRY_HARDER))) { i = 1; j = this.image.getHeight(); k = this.image.getWidth(); m = j * 3 / 228; if ((m < 3) || (i != 0)) { m = 3; } bool = false; arrayOfInt = new int[5]; n = m - 1; } for (;;) { if ((n >= j) || (bool)) { break label451; } arrayOfInt[0] = 0; arrayOfInt[1] = 0; arrayOfInt[2] = 0; arrayOfInt[3] = 0; arrayOfInt[4] = 0; int i1 = 0; int i2 = 0; label113: if (i2 < k) { if (this.image.get(i2, n)) { if ((i1 & 0x1) == 1) { i1++; } arrayOfInt[i1] = (1 + arrayOfInt[i1]); } for (;;) { i2++; break label113; i = 0; break; if ((i1 & 0x1) == 0) { if (i1 == 4) { if (foundPatternCross(arrayOfInt)) { if (handlePossibleCenter(arrayOfInt, n, i2)) { m = 2; if (this.hasSkipped) { bool = haveMultiplyConfirmedCenters(); } for (;;) { arrayOfInt[0] = 0; arrayOfInt[1] = 0; arrayOfInt[2] = 0; arrayOfInt[3] = 0; arrayOfInt[4] = 0; i1 = 0; break; int i3 = findRowSkip(); if (i3 > arrayOfInt[2]) { n += i3 - arrayOfInt[2] - m; i2 = k - 1; } } } arrayOfInt[0] = arrayOfInt[2]; arrayOfInt[1] = arrayOfInt[3]; arrayOfInt[2] = arrayOfInt[4]; arrayOfInt[3] = 1; arrayOfInt[4] = 0; i1 = 3; } else { arrayOfInt[0] = arrayOfInt[2]; arrayOfInt[1] = arrayOfInt[3]; arrayOfInt[2] = arrayOfInt[4]; arrayOfInt[3] = 1; arrayOfInt[4] = 0; i1 = 3; } } else { i1++; arrayOfInt[i1] = (1 + arrayOfInt[i1]); } } else { arrayOfInt[i1] = (1 + arrayOfInt[i1]); } } } if ((foundPatternCross(arrayOfInt)) && (handlePossibleCenter(arrayOfInt, n, k))) { m = arrayOfInt[0]; if (this.hasSkipped) { bool = haveMultiplyConfirmedCenters(); } } n += m; } label451: FinderPattern[] arrayOfFinderPattern = selectBestPatterns(); ResultPoint.orderBestPatterns(arrayOfFinderPattern); return new FinderPatternInfo(arrayOfFinderPattern); }
@SuppressWarnings("unchecked") private void doDecodeMultiple( BinaryBitmap image, @SuppressWarnings("rawtypes") Hashtable hints, @SuppressWarnings("rawtypes") Vector results, int xOffset, int yOffset) { Result result; try { result = delegate.decode(image, hints); } catch (ReaderException re) { return; } boolean alreadyFound = false; for (int i = 0; i < results.size(); i++) { Result existingResult = (Result) results.elementAt(i); if (existingResult.getText().equals(result.getText())) { alreadyFound = true; break; } } if (alreadyFound) { return; } results.addElement(translateResultPoints(result, xOffset, yOffset)); ResultPoint[] resultPoints = result.getResultPoints(); if (resultPoints == null || resultPoints.length == 0) { return; } int width = image.getWidth(); int height = image.getHeight(); float minX = width; float minY = height; float maxX = 0.0f; float maxY = 0.0f; for (int i = 0; i < resultPoints.length; i++) { ResultPoint point = resultPoints[i]; float x = point.getX(); float y = point.getY(); if (x < minX) { minX = x; } if (y < minY) { minY = y; } if (x > maxX) { maxX = x; } if (y > maxY) { maxY = y; } } // Decode left of barcode if (minX > MIN_DIMENSION_TO_RECUR) { doDecodeMultiple(image.crop(0, 0, (int) minX, height), hints, results, xOffset, yOffset); } // Decode above barcode if (minY > MIN_DIMENSION_TO_RECUR) { doDecodeMultiple(image.crop(0, 0, width, (int) minY), hints, results, xOffset, yOffset); } // Decode right of barcode if (maxX < width - MIN_DIMENSION_TO_RECUR) { doDecodeMultiple( image.crop((int) maxX, 0, width - (int) maxX, height), hints, results, xOffset + (int) maxX, yOffset); } // Decode below barcode if (maxY < height - MIN_DIMENSION_TO_RECUR) { doDecodeMultiple( image.crop(0, (int) maxY, width, height - (int) maxY), hints, results, xOffset, yOffset + (int) maxY); } }
@Override public void onDraw(Canvas canvas) { // 中间的扫描框,你要修改扫描框的大小,去CameraManager里面修改 Rect frame = CameraManager.get().getFramingRect(); if (frame == null) { return; } // 初始化中间线滑动的最上边和最下边 if (!isFirst) { isFirst = true; slideTop = frame.top; slideBottom = frame.bottom; } // 获取屏幕的宽和高 int width = canvas.getWidth(); int height = canvas.getHeight(); paint.setColor(resultBitmap != null ? resultColor : maskColor); // 画出扫描框外面的阴影部分,共四个部分,扫描框的上面到屏幕上面,扫描框的下面到屏幕下面 // 扫描框的左边面到屏幕左边,扫描框的右边到屏幕右边 canvas.drawRect(0, 0, width, frame.top, paint); canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint); canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint); canvas.drawRect(0, frame.bottom + 1, width, height, paint); if (resultBitmap != null) { // Draw the opaque result bitmap over the scanning rectangle paint.setAlpha(OPAQUE); canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint); } else { // 画扫描框边上的角,总共8个部分 paint.setColor(Color.GREEN); canvas.drawRect( frame.left, frame.top, frame.left + ScreenRate, frame.top + CORNER_WIDTH, paint); canvas.drawRect( frame.left, frame.top, frame.left + CORNER_WIDTH, frame.top + ScreenRate, paint); canvas.drawRect( frame.right - ScreenRate, frame.top, frame.right, frame.top + CORNER_WIDTH, paint); canvas.drawRect( frame.right - CORNER_WIDTH, frame.top, frame.right, frame.top + ScreenRate, paint); canvas.drawRect( frame.left, frame.bottom - CORNER_WIDTH, frame.left + ScreenRate, frame.bottom, paint); canvas.drawRect( frame.left, frame.bottom - ScreenRate, frame.left + CORNER_WIDTH, frame.bottom, paint); canvas.drawRect( frame.right - ScreenRate, frame.bottom - CORNER_WIDTH, frame.right, frame.bottom, paint); canvas.drawRect( frame.right - CORNER_WIDTH, frame.bottom - ScreenRate, frame.right, frame.bottom, paint); // 绘制中间的线,每次刷新界面,中间的线往下移动SPEEN_DISTANCE slideTop += SPEEN_DISTANCE; if (slideTop >= frame.bottom) { slideTop = frame.top; } Rect lineRect = new Rect(); lineRect.left = frame.left; lineRect.right = frame.right; lineRect.top = slideTop; lineRect.bottom = slideTop + 18; canvas.drawBitmap( ((BitmapDrawable) (getResources().getDrawable(R.drawable.qrcode_scan_line))).getBitmap(), null, lineRect, paint); // 画扫描框下面的字 paint.setColor(Color.WHITE); paint.setTextSize(TEXT_SIZE * density); paint.setAlpha(0x40); paint.setTypeface(Typeface.create("System", Typeface.BOLD)); String text = getResources().getString(R.string.scan_text); float textWidth = paint.measureText(text); canvas.drawText( text, (width - textWidth) / 2, (float) (frame.bottom + (float) TEXT_PADDING_TOP * density), paint); Collection<ResultPoint> currentPossible = possibleResultPoints; Collection<ResultPoint> currentLast = lastPossibleResultPoints; if (currentPossible.isEmpty()) { lastPossibleResultPoints = null; } else { possibleResultPoints = new HashSet<ResultPoint>(5); lastPossibleResultPoints = currentPossible; paint.setAlpha(OPAQUE); paint.setColor(resultPointColor); for (ResultPoint point : currentPossible) { canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint); } } if (currentLast != null) { paint.setAlpha(OPAQUE / 2); paint.setColor(resultPointColor); for (ResultPoint point : currentLast) { canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 3.0f, paint); } } // 只刷新扫描框的内容,其他地方不刷新 postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom); } }
@Override public void onDraw(Canvas canvas) { if (cameraManager == null) { return; // not ready yet, early draw before done configuring } Rect frame = cameraManager.getFramingRect(); Rect previewFrame = cameraManager.getFramingRectInPreview(); if (frame == null || previewFrame == null) { return; } int width = canvas.getWidth(); int height = canvas.getHeight(); // Draw the exterior (i.e. outside the framing rect) darkened paint.setColor(resultBitmap != null ? resultColor : maskColor); canvas.drawRect(0, 0, width, frame.top, paint); canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint); canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint); canvas.drawRect(0, frame.bottom + 1, width, height, paint); if (resultBitmap != null) { // Draw the opaque result bitmap over the scanning rectangle paint.setAlpha(CURRENT_POINT_OPACITY); canvas.drawBitmap(resultBitmap, null, frame, paint); } else { // Draw a red "laser scanner" line through the middle to show decoding is active paint.setColor(laserColor); paint.setAlpha(SCANNER_ALPHA[scannerAlpha]); scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length; int middle = frame.height() / 2 + frame.top; canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint); float scaleX = frame.width() / (float) previewFrame.width(); float scaleY = frame.height() / (float) previewFrame.height(); List<ResultPoint> currentPossible = possibleResultPoints; List<ResultPoint> currentLast = lastPossibleResultPoints; int frameLeft = frame.left; int frameTop = frame.top; if (currentPossible.isEmpty()) { lastPossibleResultPoints = null; } else { possibleResultPoints = new ArrayList<ResultPoint>(5); lastPossibleResultPoints = currentPossible; paint.setAlpha(CURRENT_POINT_OPACITY); paint.setColor(resultPointColor); synchronized (currentPossible) { for (ResultPoint point : currentPossible) { canvas.drawCircle( frameLeft + (int) (point.getX() * scaleX), frameTop + (int) (point.getY() * scaleY), POINT_SIZE, paint); } } } if (currentLast != null) { paint.setAlpha(CURRENT_POINT_OPACITY / 2); paint.setColor(resultPointColor); synchronized (currentLast) { float radius = POINT_SIZE / 2.0f; for (ResultPoint point : currentLast) { canvas.drawCircle( frameLeft + (int) (point.getX() * scaleX), frameTop + (int) (point.getY() * scaleY), radius, paint); } } } // Request another update at the animation interval, but only repaint the laser line, // not the entire viewfinder mask. postInvalidateDelayed( ANIMATION_DELAY, frame.left - POINT_SIZE, frame.top - POINT_SIZE, frame.right + POINT_SIZE, frame.bottom + POINT_SIZE); } }
// TODO implement properly // TODO maybe we should add missing codewords to store the correct row number to make // finding row numbers for other columns easier // use row height count to make detection of invalid row numbers more reliable int adjustCompleteIndicatorColumnRowNumbers(BarcodeMetadata barcodeMetadata) { Codeword[] codewords = getCodewords(); setRowNumbers(); removeIncorrectCodewords(codewords, barcodeMetadata); BoundingBox boundingBox = getBoundingBox(); ResultPoint top = isLeft ? boundingBox.getTopLeft() : boundingBox.getTopRight(); ResultPoint bottom = isLeft ? boundingBox.getBottomLeft() : boundingBox.getBottomRight(); int firstRow = imageRowToCodewordIndex((int) top.getY()); int lastRow = imageRowToCodewordIndex((int) bottom.getY()); // We need to be careful using the average row height. Barcode could be skewed so that we have // smaller and // taller rows float averageRowHeight = (lastRow - firstRow) / (float) barcodeMetadata.getRowCount(); int barcodeRow = -1; int maxRowHeight = 1; int currentRowHeight = 0; for (int codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) { if (codewords[codewordsRow] == null) { continue; } Codeword codeword = codewords[codewordsRow]; // float expectedRowNumber = (codewordsRow - firstRow) / averageRowHeight; // if (Math.abs(codeword.getRowNumber() - expectedRowNumber) > 2) { // SimpleLog.log(LEVEL.WARNING, // "Removing codeword, rowNumberSkew too high, codeword[" + codewordsRow + "]: // Expected Row: " + // expectedRowNumber + ", RealRow: " + codeword.getRowNumber() + ", value: " + // codeword.getValue()); // codewords[codewordsRow] = null; // } int rowDifference = codeword.getRowNumber() - barcodeRow; // TODO improve handling with case where first row indicator doesn't start with 0 if (rowDifference == 0) { currentRowHeight++; } else if (rowDifference == 1) { maxRowHeight = Math.max(maxRowHeight, currentRowHeight); currentRowHeight = 1; barcodeRow = codeword.getRowNumber(); } else if (rowDifference < 0 || codeword.getRowNumber() >= barcodeMetadata.getRowCount() || rowDifference > codewordsRow) { codewords[codewordsRow] = null; } else { int checkedRows; if (maxRowHeight > 2) { checkedRows = (maxRowHeight - 2) * rowDifference; } else { checkedRows = rowDifference; } boolean closePreviousCodewordFound = checkedRows >= codewordsRow; for (int i = 1; i <= checkedRows && !closePreviousCodewordFound; i++) { // there must be (height * rowDifference) number of codewords missing. For now we assume // height = 1. // This should hopefully get rid of most problems already. closePreviousCodewordFound = codewords[codewordsRow - i] != null; } if (closePreviousCodewordFound) { codewords[codewordsRow] = null; } else { barcodeRow = codeword.getRowNumber(); currentRowHeight = 1; } } } return (int) (averageRowHeight + 0.5); }
protected static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b) { canvas.drawLine(a.getX(), a.getY(), b.getX(), b.getY(), paint); }
private ResultPoint correctTopRight(ResultPoint resultpoint, ResultPoint resultpoint1, ResultPoint resultpoint2, ResultPoint resultpoint3, int i) { ResultPoint resultpoint4; float f = (float)distance(resultpoint, resultpoint1) / (float)i; int j = distance(resultpoint2, resultpoint3); float f1 = (resultpoint3.getX() - resultpoint2.getX()) / (float)j; float f2 = (resultpoint3.getY() - resultpoint2.getY()) / (float)j; resultpoint4 = new ResultPoint(resultpoint3.getX() + f * f1, resultpoint3.getY() + f * f2); f = (float)distance(resultpoint, resultpoint2) / (float)i; i = distance(resultpoint1, resultpoint3); f1 = (resultpoint3.getX() - resultpoint1.getX()) / (float)i; f2 = (resultpoint3.getY() - resultpoint1.getY()) / (float)i; resultpoint3 = new ResultPoint(resultpoint3.getX() + f * f1, resultpoint3.getY() + f * f2); if (isValid(resultpoint4)) goto _L2; else goto _L1