예제 #1
0
  @Override
  protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);

    // Draw translucent background for the cropped area.
    switch (cropType) {
      case RECT:
        drawBackground(canvas, mBitmapRect);
        break;
      case OVAL:
        drawOvalBackground(canvas, mBitmapRect);
        break;
      default:
        break;
    }

    if (showGuidelines()) {
      // Determines whether guidelines should be drawn or not
      if (mGuidelines == GUIDELINES_ON) {
        drawRuleOfThirdsGuidelines(canvas);
      } else if (mGuidelines == GUIDELINES_ON_TOUCH) {
        // Draw only when resizing
        if (mPressedHandle != null) drawRuleOfThirdsGuidelines(canvas);
      } else if (mGuidelines == GUIDELINES_OFF) {
        // Do nothing
      }
    }

    switch (cropType) {
      case RECT:
        // Draws the main crop window border.
        canvas.drawRect(
            Edge.LEFT.getCoordinate(),
            Edge.TOP.getCoordinate(),
            Edge.RIGHT.getCoordinate(),
            Edge.BOTTOM.getCoordinate(),
            mBorderPaint);
        break;
      case OVAL:
        oval.set(
            Edge.LEFT.getCoordinate(),
            Edge.TOP.getCoordinate(),
            Edge.RIGHT.getCoordinate(),
            Edge.BOTTOM.getCoordinate());
        canvas.drawOval(oval, mBorderPaint);
        break;
      default:
        break;
    }

    drawCorners(canvas);
  }
예제 #2
0
  private void drawBackground(Canvas canvas, Rect bitmapRect) {

    final float left = Edge.LEFT.getCoordinate();
    final float top = Edge.TOP.getCoordinate();
    final float right = Edge.RIGHT.getCoordinate();
    final float bottom = Edge.BOTTOM.getCoordinate();

    /*-
     -------------------------------------
     |                top                |
     -------------------------------------
     |      |                    |       |
     |      |                    |       |
     | left |                    | right |
     |      |                    |       |
     |      |                    |       |
     -------------------------------------
     |              bottom               |
     -------------------------------------
    */

    // Draw "top", "bottom", "left", then "right" quadrants.
    canvas.drawRect(bitmapRect.left, bitmapRect.top, bitmapRect.right, top, mBackgroundPaint);
    canvas.drawRect(bitmapRect.left, bottom, bitmapRect.right, bitmapRect.bottom, mBackgroundPaint);
    canvas.drawRect(bitmapRect.left, top, left, bottom, mBackgroundPaint);
    canvas.drawRect(right, top, bitmapRect.right, bottom, mBackgroundPaint);
  }
예제 #3
0
 /**
  * Indicates whether the crop window is small enough that the guidelines should be shown. Public
  * because this function is also used to determine if the center handle should be focused.
  *
  * @return boolean Whether the guidelines should be shown or not
  */
 public static boolean showGuidelines() {
   if ((Math.abs(Edge.LEFT.getCoordinate() - Edge.RIGHT.getCoordinate())
           < DEFAULT_SHOW_GUIDELINES_LIMIT)
       || (Math.abs(Edge.TOP.getCoordinate() - Edge.BOTTOM.getCoordinate())
           < DEFAULT_SHOW_GUIDELINES_LIMIT)) return false;
   else return true;
 }
예제 #4
0
 private void drawOvalBackground(Canvas canvas, Rect bitmapRect) {
   final float left = Edge.LEFT.getCoordinate();
   final float top = Edge.TOP.getCoordinate();
   final float right = Edge.RIGHT.getCoordinate();
   final float bottom = Edge.BOTTOM.getCoordinate();
   RectF r = new RectF(left, top, right, bottom);
   Path path = new Path();
   path.addRect(
       bitmapRect.left, bitmapRect.top, bitmapRect.right, bitmapRect.bottom, Path.Direction.CW);
   path.addOval(r, Path.Direction.CCW);
   path.setFillType(Path.FillType.EVEN_ODD);
   canvas.drawPath(path, mBackgroundPaint);
 }
예제 #5
0
  private void drawCorners(Canvas canvas) {

    final float left = Edge.LEFT.getCoordinate();
    final float top = Edge.TOP.getCoordinate();
    final float right = Edge.RIGHT.getCoordinate();
    final float bottom = Edge.BOTTOM.getCoordinate();

    // Draws the corner lines

    // Top left
    canvas.drawLine(
        left - mCornerOffset,
        top - mCornerExtension,
        left - mCornerOffset,
        top + mCornerLength,
        mCornerPaint);
    canvas.drawLine(
        left, top - mCornerOffset, left + mCornerLength, top - mCornerOffset, mCornerPaint);

    // Top right
    canvas.drawLine(
        right + mCornerOffset,
        top - mCornerExtension,
        right + mCornerOffset,
        top + mCornerLength,
        mCornerPaint);
    canvas.drawLine(
        right, top - mCornerOffset, right - mCornerLength, top - mCornerOffset, mCornerPaint);

    // Bottom left
    canvas.drawLine(
        left - mCornerOffset,
        bottom + mCornerExtension,
        left - mCornerOffset,
        bottom - mCornerLength,
        mCornerPaint);
    canvas.drawLine(
        left, bottom + mCornerOffset, left + mCornerLength, bottom + mCornerOffset, mCornerPaint);

    // Bottom left
    canvas.drawLine(
        right + mCornerOffset,
        bottom + mCornerExtension,
        right + mCornerOffset,
        bottom - mCornerLength,
        mCornerPaint);
    canvas.drawLine(
        right, bottom + mCornerOffset, right - mCornerLength, bottom + mCornerOffset, mCornerPaint);
  }
예제 #6
0
  /**
   * Handles a {@link MotionEvent#ACTION_DOWN} event.
   *
   * @param x the x-coordinate of the down action
   * @param y the y-coordinate of the down action
   */
  private void onActionDown(float x, float y) {

    final float left = Edge.LEFT.getCoordinate();
    final float top = Edge.TOP.getCoordinate();
    final float right = Edge.RIGHT.getCoordinate();
    final float bottom = Edge.BOTTOM.getCoordinate();

    mPressedHandle = HandleUtil.getPressedHandle(x, y, left, top, right, bottom, mHandleRadius);

    if (mPressedHandle == null) return;

    // Calculate the offset of the touch point from the precise location
    // of the handle. Save these values in a member variable since we want
    // to maintain this offset as we drag the handle.
    mTouchOffset = HandleUtil.getOffset(mPressedHandle, x, y, left, top, right, bottom);

    invalidate();
  }
예제 #7
0
  @Override
  void updateCropWindow(float x, float y, @NonNull RectF imageRect, float snapRadius) {

    float left = Edge.LEFT.getCoordinate();
    float top = Edge.TOP.getCoordinate();
    float right = Edge.RIGHT.getCoordinate();
    float bottom = Edge.BOTTOM.getCoordinate();

    final float currentCenterX = (left + right) / 2;
    final float currentCenterY = (top + bottom) / 2;

    final float offsetX = x - currentCenterX;
    final float offsetY = y - currentCenterY;

    // Adjust the crop window.
    Edge.LEFT.offset(offsetX);
    Edge.TOP.offset(offsetY);
    Edge.RIGHT.offset(offsetX);
    Edge.BOTTOM.offset(offsetY);

    // Check if we have gone out of bounds on the sides, and fix.
    if (Edge.LEFT.isOutsideMargin(imageRect, snapRadius)) {
      final float offset = Edge.LEFT.snapToRect(imageRect);
      Edge.RIGHT.offset(offset);
    } else if (Edge.RIGHT.isOutsideMargin(imageRect, snapRadius)) {
      final float offset = Edge.RIGHT.snapToRect(imageRect);
      Edge.LEFT.offset(offset);
    }

    // Check if we have gone out of bounds on the top or bottom, and fix.
    if (Edge.TOP.isOutsideMargin(imageRect, snapRadius)) {
      final float offset = Edge.TOP.snapToRect(imageRect);
      Edge.BOTTOM.offset(offset);
    } else if (Edge.BOTTOM.isOutsideMargin(imageRect, snapRadius)) {
      final float offset = Edge.BOTTOM.snapToRect(imageRect);
      Edge.TOP.offset(offset);
    }
  }
  /**
   * Gets the cropped image based on the current crop window.
   *
   * @return a new Bitmap representing the cropped image
   */
  public Bitmap getCroppedImage() {

    final Rect displayedImageRect = ImageViewUtil.getBitmapRectCenterInside(mBitmap, mImageView);
    // Get the scale factor between the actual Bitmap dimensions and the
    // displayed dimensions for width.
    final float actualImageWidth = mBitmap.getWidth();
    final float displayedImageWidth = displayedImageRect.width();
    final float scaleFactorWidth = actualImageWidth / displayedImageWidth;

    // Get the scale factor between the actual Bitmap dimensions and the
    // displayed dimensions for height.
    final float actualImageHeight = mBitmap.getHeight();
    final float displayedImageHeight = displayedImageRect.height();
    final float scaleFactorHeight = actualImageHeight / displayedImageHeight;

    // Get crop window position relative to the displayed image.
    final float cropWindowX = Edge.LEFT.getCoordinate() - displayedImageRect.left;
    final float cropWindowY = Edge.TOP.getCoordinate() - displayedImageRect.top;
    final float cropWindowWidth = Edge.getWidth();
    final float cropWindowHeight = Edge.getHeight();

    // Scale the crop window position to the actual size of the Bitmap.
    final float actualCropX = cropWindowX * scaleFactorWidth;
    final float actualCropY = cropWindowY * scaleFactorHeight;
    final float actualCropWidth = cropWindowWidth * scaleFactorWidth;
    final float actualCropHeight = cropWindowHeight * scaleFactorHeight;

    // Cropget the subset from the original Bitmap.
    final Bitmap croppedBitmap =
        Bitmap.createBitmap(
            mBitmap,
            (int) actualCropX,
            (int) actualCropY,
            (int) actualCropWidth,
            (int) actualCropHeight);

    return croppedBitmap;
  }
예제 #9
0
  private void drawRuleOfThirdsGuidelines(Canvas canvas) {

    final float left = Edge.LEFT.getCoordinate();
    final float top = Edge.TOP.getCoordinate();
    final float right = Edge.RIGHT.getCoordinate();
    final float bottom = Edge.BOTTOM.getCoordinate();

    // Draw vertical guidelines.
    final float oneThirdCropWidth = Edge.getWidth() / 3;

    final float x1 = left + oneThirdCropWidth;
    canvas.drawLine(x1, top, x1, bottom, mGuidelinePaint);
    final float x2 = right - oneThirdCropWidth;
    canvas.drawLine(x2, top, x2, bottom, mGuidelinePaint);

    // Draw horizontal guidelines.
    final float oneThirdCropHeight = Edge.getHeight() / 3;

    final float y1 = top + oneThirdCropHeight;
    canvas.drawLine(left, y1, right, y1, mGuidelinePaint);
    final float y2 = bottom - oneThirdCropHeight;
    canvas.drawLine(left, y2, right, y2, mGuidelinePaint);
  }
예제 #10
0
  /**
   * Set the initial crop window size and position. This is dependent on the size and position of
   * the image being cropped.
   *
   * @param bitmapRect the bounding box around the image being cropped
   */
  private void initCropWindow(Rect bitmapRect) {

    // Tells the attribute functions the crop window has already been
    // initialized
    if (initializedCropWindow == false) initializedCropWindow = true;

    if (mFixAspectRatio) {

      // If the image aspect ratio is wider than the crop aspect ratio,
      // then the image height is the determining initial length. Else,
      // vice-versa.
      if (AspectRatioUtil.calculateAspectRatio(bitmapRect) > mTargetAspectRatio) {

        Edge.TOP.setCoordinate(bitmapRect.top);
        Edge.BOTTOM.setCoordinate(bitmapRect.bottom);

        final float centerX = getWidth() / 2f;

        // Limits the aspect ratio to no less than 40 wide or 40 tall
        final float cropWidth =
            Math.max(
                Edge.MIN_CROP_LENGTH_PX,
                AspectRatioUtil.calculateWidth(
                    Edge.TOP.getCoordinate(), Edge.BOTTOM.getCoordinate(), mTargetAspectRatio));

        // Create new TargetAspectRatio if the original one does not fit
        // the screen
        if (cropWidth == Edge.MIN_CROP_LENGTH_PX)
          mTargetAspectRatio =
              (Edge.MIN_CROP_LENGTH_PX) / (Edge.BOTTOM.getCoordinate() - Edge.TOP.getCoordinate());

        final float halfCropWidth = cropWidth / 2f;
        Edge.LEFT.setCoordinate(centerX - halfCropWidth);
        Edge.RIGHT.setCoordinate(centerX + halfCropWidth);

      } else {

        Edge.LEFT.setCoordinate(bitmapRect.left);
        Edge.RIGHT.setCoordinate(bitmapRect.right);

        final float centerY = getHeight() / 2f;

        // Limits the aspect ratio to no less than 40 wide or 40 tall
        final float cropHeight =
            Math.max(
                Edge.MIN_CROP_LENGTH_PX,
                AspectRatioUtil.calculateHeight(
                    Edge.LEFT.getCoordinate(), Edge.RIGHT.getCoordinate(), mTargetAspectRatio));

        // Create new TargetAspectRatio if the original one does not fit
        // the screen
        if (cropHeight == Edge.MIN_CROP_LENGTH_PX)
          mTargetAspectRatio =
              (Edge.RIGHT.getCoordinate() - Edge.LEFT.getCoordinate()) / Edge.MIN_CROP_LENGTH_PX;

        final float halfCropHeight = cropHeight / 2f;
        Edge.TOP.setCoordinate(centerY - halfCropHeight);
        Edge.BOTTOM.setCoordinate(centerY + halfCropHeight);
      }

    } else { // ... do not fix aspect ratio...

      // Initialize crop window to have 10% padding w/ respect to image.
      final float horizontalPadding = 0.1f * bitmapRect.width();
      final float verticalPadding = 0.1f * bitmapRect.height();

      Edge.LEFT.setCoordinate(bitmapRect.left + horizontalPadding);
      Edge.TOP.setCoordinate(bitmapRect.top + verticalPadding);
      Edge.RIGHT.setCoordinate(bitmapRect.right - horizontalPadding);
      Edge.BOTTOM.setCoordinate(bitmapRect.bottom - verticalPadding);
    }
  }