Beispiel #1
0
 /**
  * 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);
        }
      }
    }
  }
Beispiel #5
0
 /**
  * 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);
   }
 }
Beispiel #8
0
 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);
   }
 }
Beispiel #9
0
  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;
  }
Beispiel #13
0
 /**
  * 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;
   }
 }
Beispiel #22
0
 /**
  * 绘制可疑点
  *
  * @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);
     }
   }
 }
Beispiel #23
0
  @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);
 }
Beispiel #30
0
 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