// 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())));
 }
  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());
  }
Esempio n. 3
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
  }
  @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);
    }
  }
 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);
   }
 }
Esempio n. 6
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);
   }
 }
  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);
        }
      }
    }
  }
  /**
   * @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;
  }
Esempio n. 9
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);
         }
       }
     }
   }
 }
Esempio n. 10
0
  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();
              }
            });
  }
 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());
 }
  /**
   * 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);
  }
Esempio n. 13
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);
     }
   }
 }
 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)
         });
     }
 }
  // 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);
  }
  /**
   * 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;
  }
Esempio n. 17
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
  /**
   * Calculates the position of the white top right module using the output of the rectangle
   * detector
   */
  private ResultPoint correctTopRight(
      ResultPoint bottomLeft,
      ResultPoint bottomRight,
      ResultPoint topLeft,
      ResultPoint topRight,
      int dimension) {

    float corr = distance(bottomLeft, bottomRight) / (float) dimension;
    int norm = distance(topLeft, topRight);
    float cos = (topRight.getX() - topLeft.getX()) / norm;
    float sin = (topRight.getY() - topLeft.getY()) / norm;

    ResultPoint c1 = new ResultPoint(topRight.getX() + corr * cos, topRight.getY() + corr * sin);

    corr = distance(bottomLeft, bottomRight) / (float) dimension;
    norm = distance(bottomRight, topRight);
    cos = (topRight.getX() - bottomRight.getX()) / norm;
    sin = (topRight.getY() - bottomRight.getY()) / norm;

    ResultPoint c2 = new ResultPoint(topRight.getX() + corr * cos, topRight.getY() + corr * sin);

    if (!isValid(c1)) {
      if (isValid(c2)) {
        return c2;
      }
      return null;
    } else if (!isValid(c2)) {
      return c1;
    }

    int l1 =
        Math.abs(
            transitionsBetween(topLeft, c1).getTransitions()
                - transitionsBetween(bottomRight, c1).getTransitions());
    int l2 =
        Math.abs(
            transitionsBetween(topLeft, c2).getTransitions()
                - transitionsBetween(bottomRight, c2).getTransitions());

    if (l1 <= l2) {
      return c1;
    }

    return c2;
  }
Esempio n. 19
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 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);
        }
      }
    }
  }
  @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);
    }
  }
  @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);
    }
  }
Esempio n. 22
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);
    }
  }
 private boolean isValid(ResultPoint p) {
   return (p.getX() >= 0 && p.getX() < image.width && p.getY() > 0 && p.getY() < image.height);
 }
  @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);
    }
  }
 protected static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b) {
   canvas.drawLine(a.getX(), a.getY(), b.getX(), b.getY(), paint);
 }
  // 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);
  }