Пример #1
0
        // Create a default HightlightView if we found no face in the picture.
        private void makeDefault() {

          HighlightView hv = new HighlightView(mImageView);

          int width = mBitmap.getWidth();
          int height = mBitmap.getHeight();

          Rect imageRect = new Rect(0, 0, width, height);

          // make the default size about 4/5 of the width or height
          int cropWidth = Math.min(width, height) * 4 / 5;
          int cropHeight = cropWidth;

          if (mAspectX != 0 && mAspectY != 0) {

            if (mAspectX > mAspectY) {

              cropHeight = cropWidth * mAspectY / mAspectX;
            } else {

              cropWidth = cropHeight * mAspectX / mAspectY;
            }
          }

          int x = (width - cropWidth) / 2;
          int y = (height - cropHeight) / 2;

          RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight);
          hv.setup(mImageMatrix, imageRect, cropRect, mCircleCrop, mAspectX != 0 && mAspectY != 0);

          mImageView.mHighlightViews.clear(); // Thong added for rotate

          mImageView.add(hv);
        }
Пример #2
0
  @Override
  protected void zoomOut() {

    super.zoomOut();
    for (HighlightView hv : mHighlightViews) {
      hv.mMatrix.set(getImageMatrix());
      hv.invalidate();
    }
  }
Пример #3
0
  @Override
  protected void zoomTo(float scale, float centerX, float centerY) {

    super.zoomTo(scale, centerX, centerY);
    for (HighlightView hv : mHighlightViews) {
      hv.mMatrix.set(getImageMatrix());
      hv.invalidate();
    }
  }
Пример #4
0
  @Override
  protected void postTranslate(float deltaX, float deltaY) {

    super.postTranslate(deltaX, deltaY);
    for (int i = 0; i < mHighlightViews.size(); i++) {
      HighlightView hv = mHighlightViews.get(i);
      hv.mMatrix.postTranslate(deltaX, deltaY);
      hv.invalidate();
    }
  }
Пример #5
0
  @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

    super.onLayout(changed, left, top, right, bottom);
    if (mBitmapDisplayed.getBitmap() != null) {
      for (HighlightView hv : mHighlightViews) {
        hv.mMatrix.set(getImageMatrix());
        hv.invalidate();
        if (hv.mIsFocused) {
          centerBasedOnHighlightView(hv);
        }
      }
    }
  }
Пример #6
0
        // For each face, we create a HightlightView for it.
        private void handleFace(FaceDetector.Face f) {

          PointF midPoint = new PointF();

          int r = ((int) (f.eyesDistance() * mScale)) * 2;
          f.getMidPoint(midPoint);
          midPoint.x *= mScale;
          midPoint.y *= mScale;

          int midX = (int) midPoint.x;
          int midY = (int) midPoint.y;

          HighlightView hv = new HighlightView(mImageView);

          int width = mBitmap.getWidth();
          int height = mBitmap.getHeight();

          Rect imageRect = new Rect(0, 0, width, height);

          RectF faceRect = new RectF(midX, midY, midX, midY);
          faceRect.inset(-r, -r);
          if (faceRect.left < 0) {
            faceRect.inset(-faceRect.left, -faceRect.left);
          }

          if (faceRect.top < 0) {
            faceRect.inset(-faceRect.top, -faceRect.top);
          }

          if (faceRect.right > imageRect.right) {
            faceRect.inset(faceRect.right - imageRect.right, faceRect.right - imageRect.right);
          }

          if (faceRect.bottom > imageRect.bottom) {
            faceRect.inset(faceRect.bottom - imageRect.bottom, faceRect.bottom - imageRect.bottom);
          }

          hv.setup(mImageMatrix, imageRect, faceRect, mCircleCrop, mAspectX != 0 && mAspectY != 0);

          mImageView.add(hv);
        }
Пример #7
0
  // According to the event's position, change the focus to the first
  // hitting cropping rectangle.
  private void recomputeFocus(MotionEvent event) {

    for (int i = 0; i < mHighlightViews.size(); i++) {
      HighlightView hv = mHighlightViews.get(i);
      hv.setFocus(false);
      hv.invalidate();
    }

    for (int i = 0; i < mHighlightViews.size(); i++) {
      HighlightView hv = mHighlightViews.get(i);
      int edge = hv.getHit(event.getX(), event.getY());
      if (edge != HighlightView.GROW_NONE) {
        if (!hv.hasFocus()) {
          hv.setFocus(true);
          hv.invalidate();
        }
        break;
      }
    }
    invalidate();
  }
Пример #8
0
  private void onSaveClicked() throws Exception {
    // TODO this code needs to change to use the decode/crop/encode single
    // step api so that we don't require that the whole (possibly large)
    // bitmap doesn't have to be read into memory
    if (mSaving) return;

    if (mCrop == null) {

      return;
    }

    mSaving = true;

    Rect r = mCrop.getCropRect();

    int width = r.width();
    int height = r.height();

    // If we are circle cropping, we want alpha channel, which is the
    // third param here.
    Bitmap croppedImage;
    try {

      croppedImage =
          Bitmap.createBitmap(
              width, height, mCircleCrop ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
    } catch (Exception e) {
      throw e;
    }
    if (croppedImage == null) {

      return;
    }

    {
      Canvas canvas = new Canvas(croppedImage);
      Rect dstRect = new Rect(0, 0, width, height);
      canvas.drawBitmap(mBitmap, r, dstRect, null);
    }

    if (mCircleCrop) {

      // OK, so what's all this about?
      // Bitmaps are inherently rectangular but we want to return
      // something that's basically a circle.  So we fill in the
      // area around the circle with alpha.  Note the all important
      // PortDuff.Mode.CLEAR.
      Canvas c = new Canvas(croppedImage);
      Path p = new Path();
      p.addCircle(width / 2F, height / 2F, width / 2F, Path.Direction.CW);
      c.clipPath(p, Region.Op.DIFFERENCE);
      c.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
    }

    /* If the output is required to a specific size then scale or fill */
    if (mOutputX != 0 && mOutputY != 0) {

      if (mScale) {

        /* Scale the image to the required dimensions */
        Bitmap old = croppedImage;
        croppedImage = Util.transform(new Matrix(), croppedImage, mOutputX, mOutputY, mScaleUp);
        if (old != croppedImage) {

          old.recycle();
        }
      } else {

        /* Don't scale the image crop it to the size requested.
         * Create an new image with the cropped image in the center and
         * the extra space filled.
         */

        // Don't scale the image but instead fill it so it's the
        // required dimension
        Bitmap b = Bitmap.createBitmap(mOutputX, mOutputY, Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(b);

        Rect srcRect = mCrop.getCropRect();
        Rect dstRect = new Rect(0, 0, mOutputX, mOutputY);

        int dx = (srcRect.width() - dstRect.width()) / 2;
        int dy = (srcRect.height() - dstRect.height()) / 2;

        /* If the srcRect is too big, use the center part of it. */
        srcRect.inset(Math.max(0, dx), Math.max(0, dy));

        /* If the dstRect is too big, use the center part of it. */
        dstRect.inset(Math.max(0, -dx), Math.max(0, -dy));

        /* Draw the cropped bitmap in the center */
        canvas.drawBitmap(mBitmap, srcRect, dstRect, null);

        /* Set the cropped bitmap as the new bitmap */
        croppedImage.recycle();
        croppedImage = b;
      }
    }

    // Return the cropped image directly or save it to the specified URI.
    Bundle myExtras = getIntent().getExtras();
    if (myExtras != null
        && (myExtras.getParcelable("data") != null || myExtras.getBoolean(RETURN_DATA))) {

      Bundle extras = new Bundle();
      extras.putParcelable(RETURN_DATA_AS_BITMAP, croppedImage);
      setResult(RESULT_OK, (new Intent()).setAction(ACTION_INLINE_DATA).putExtras(extras));
      finish();
    } else {
      final Bitmap b = croppedImage;
      Util.startBackgroundJob(
          this,
          null,
          getString(R.string.saving_image),
          new Runnable() {
            public void run() {

              saveOutput(b);
            }
          },
          mHandler);
    }
  }
Пример #9
0
  @Override
  public boolean onTouchEvent(MotionEvent event) {

    CropImage cropImage = (CropImage) mContext;
    if (cropImage.mSaving) {
      return false;
    }

    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        if (cropImage.mWaitingToPick) {
          recomputeFocus(event);
        } else {
          for (int i = 0; i < mHighlightViews.size(); i++) {
            HighlightView hv = mHighlightViews.get(i);
            int edge = hv.getHit(event.getX(), event.getY());
            if (edge != HighlightView.GROW_NONE) {
              mMotionEdge = edge;
              mMotionHighlightView = hv;
              mLastX = event.getX();
              mLastY = event.getY();
              mMotionHighlightView.setMode(
                  (edge == HighlightView.MOVE)
                      ? HighlightView.ModifyMode.Move
                      : HighlightView.ModifyMode.Grow);
              break;
            }
          }
        }
        break;
      case MotionEvent.ACTION_UP:
        if (cropImage.mWaitingToPick) {
          for (int i = 0; i < mHighlightViews.size(); i++) {
            HighlightView hv = mHighlightViews.get(i);
            if (hv.hasFocus()) {
              cropImage.mCrop = hv;
              for (int j = 0; j < mHighlightViews.size(); j++) {
                if (j == i) {
                  continue;
                }
                mHighlightViews.get(j).setHidden(true);
              }
              centerBasedOnHighlightView(hv);
              ((CropImage) mContext).mWaitingToPick = false;
              return true;
            }
          }
        } else if (mMotionHighlightView != null) {
          centerBasedOnHighlightView(mMotionHighlightView);
          mMotionHighlightView.setMode(HighlightView.ModifyMode.None);
        }
        mMotionHighlightView = null;
        break;
      case MotionEvent.ACTION_MOVE:
        if (cropImage.mWaitingToPick) {
          recomputeFocus(event);
        } else if (mMotionHighlightView != null) {
          mMotionHighlightView.handleMotion(
              mMotionEdge, event.getX() - mLastX, event.getY() - mLastY);
          mLastX = event.getX();
          mLastY = event.getY();

          if (true) {
            // This section of code is optional. It has some user
            // benefit in that moving the crop rectangle against
            // the edge of the screen causes scrolling but it means
            // that the crop rectangle is no longer fixed under
            // the user's finger.
            ensureVisible(mMotionHighlightView);
          }
        }
        break;
    }

    switch (event.getAction()) {
      case MotionEvent.ACTION_UP:
        center(true, true);
        break;
      case MotionEvent.ACTION_MOVE:
        // if we're not zoomed then there's no point in even allowing
        // the user to move the image around.  This call to center puts
        // it back to the normalized location (with false meaning don't
        // animate).
        if (getScale() == 1F) {
          center(true, true);
        }
        break;
    }

    return true;
  }