// According to the event's position, change the focus to the first // hitting cropping rectangle. private void RecomputeFocus(MotionEvent e) { int count = this.MotionHighlightViews.Count; for (int i = 0; i < count; i++) { EmHighlightView hv = this.MotionHighlightViews [i]; hv.Focused = false; hv.Invalidate(); } for (int i = 0; i < count; i++) { EmHighlightView hv = this.MotionHighlightViews [i]; int edge = hv.GetHit(e.GetX(), e.GetY()); if (edge != HighlightView.GrowNone) { if (!hv.Focused) { hv.Focused = true; hv.Invalidate(); } break; } } this.Invalidate(); }
// If the cropping rectangle's size changed significantly, change the // view's center and scale according to the cropping rectangle. private void CenterBasedOnHighlightView(EmHighlightView hv) { Rect drawRect = hv.MDrawRect; float width = drawRect.Width(); float height = drawRect.Height(); float thisWidth = this.Width; float thisHeight = this.Height; float z1 = thisWidth / width * .6F; float z2 = thisHeight / height * .6F; float zoom = Math.Min(z1, z2); zoom = zoom * this.GetScale(); zoom = Math.Max(1F, zoom); if ((Math.Abs(zoom - this.GetScale()) / zoom) > .1) { float [] coordinates = new float[] { hv.MCropRect.CenterX(), hv.MCropRect.CenterY() }; this.ImageMatrix.MapPoints(coordinates); ZoomTo(zoom, coordinates[0], coordinates[1], 300F); } EnsureVisible(hv); }
// For each face, we create a HightlightView for it. private void HandleFace(FaceDetector.Face f) { EmCropImage eci = this.ECI; if (eci == null) { return; } PointF midPoint = new PointF(); int r = ((int)(f.EyesDistance() * this.Scale)) * 2; f.GetMidPoint(midPoint); midPoint.X *= this.Scale; midPoint.Y *= this.Scale; int midX = (int)midPoint.X; int midY = (int)midPoint.Y; EmHighlightView hv = new EmHighlightView(eci.ImageView, eci.MOutlineColor, eci.MOutlineCircleColor); int width = eci.Bitmap.Width; int height = eci.Bitmap.Height; 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(this.MImageMatrix, imageRect, faceRect, eci.CircleCropping, eci.AspectX != 0 && eci.AspectY != 0); eci.ImageView.Add(hv); }
protected override void PostTranslate(float deltaX, float deltaY) { base.PostTranslate(deltaX, deltaY); int count = this.MotionHighlightViews.Count; for (int i = 0; i < count; i++) { EmHighlightView hv = this.MotionHighlightViews [i]; hv.Matrix.PostTranslate(deltaX, deltaY); hv.Invalidate(); } }
// Pan the displayed image to make sure the cropping rectangle is visible. private void EnsureVisible(EmHighlightView hv) { Rect r = hv.MDrawRect; int panDeltaX1 = Math.Max(0, this.Left - r.Left); int panDeltaX2 = Math.Min(0, this.Right - r.Right); int panDeltaY1 = Math.Max(0, this.Top - r.Top); int panDeltaY2 = Math.Min(0, this.Bottom - r.Bottom); int panDeltaX = panDeltaX1 != 0 ? panDeltaX1 : panDeltaX2; int panDeltaY = panDeltaY1 != 0 ? panDeltaY1 : panDeltaY2; if (panDeltaX != 0 || panDeltaY != 0) { this.PanBy(panDeltaX, panDeltaY); } }
private void MakeDefault() { EmCropImage eci = this.ECI; if (eci == null) { return; } EmHighlightView hv = new EmHighlightView(eci.ImageView, eci.MOutlineColor, eci.MOutlineCircleColor); int width = eci.Bitmap.Width; int height = eci.Bitmap.Height; Rect imageRect = new Rect(0, 0, width, height); // make the default size about 4/5 of the width or height int cropWidth = Java.Lang.Math.Min(width, height) * 4 / 5; int cropHeight = cropWidth; if (eci.AspectX != 0 && eci.AspectY != 0) { if (eci.AspectX > eci.AspectY) { cropHeight = cropWidth * eci.AspectY / eci.AspectX; } else { cropWidth = cropHeight * eci.AspectX / eci.AspectY; } } int x = (width - cropWidth) / 2; int y = (height - cropHeight) / 2; RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight); hv.Setup(this.MImageMatrix, imageRect, cropRect, eci.CircleCropping, eci.AspectX != 0 && eci.AspectY != 0); eci.ImageView.Add(hv); }
public void Add(EmHighlightView hv) { this.MotionHighlightViews.Add(hv); this.Invalidate(); }
public override bool OnTouchEvent(MotionEvent e) { EmCropImage cropImage = (EmCropImage)this.Context; if (cropImage.Saving) { return(false); } switch (e.Action) { case MotionEventActions.Down: { if (cropImage.WaitingToPick) { RecomputeFocus(e); } else { for (int i = 0; i < this.MotionHighlightViews.Count; i++) { EmHighlightView hv = this.MotionHighlightViews [i]; int edge = hv.GetHit(e.GetX(), e.GetY()); if (edge != HighlightView.GrowNone) { this.MotionEdge = edge; this.MotionHighlightView = hv; this.LastX = e.GetX(); this.LastY = e.GetY(); this.MotionHighlightView.SetMode( (edge == EmHighlightView.MOVE) ? EmHighlightView.ModifyMode.Move : EmHighlightView.ModifyMode.Grow); break; } } } break; } case MotionEventActions.Up: { if (cropImage.WaitingToPick) { for (int i = 0; i < this.MotionHighlightViews.Count; i++) { EmHighlightView hv = this.MotionHighlightViews [i]; if (hv.Focused) { cropImage.MCrop = hv; for (int j = 0; j < this.MotionHighlightViews.Count; j++) { if (j == i) { continue; } this.MotionHighlightViews [j].Hidden = true; } CenterBasedOnHighlightView(hv); ((EmCropImage)this.Context).WaitingToPick = false; return(true); } } } else { if (this.MotionHighlightView != null) { CenterBasedOnHighlightView(this.MotionHighlightView); this.MotionHighlightView.SetMode(EmHighlightView.ModifyMode.None); } } this.MotionHighlightView = null; break; } case MotionEventActions.Move: { if (cropImage.WaitingToPick) { RecomputeFocus(e); } else { if (this.MotionHighlightView != null) { this.MotionHighlightView.HandleMotion(this.MotionEdge, e.GetX() - this.LastX, e.GetY() - this.LastY); this.LastX = e.GetX(); this.LastY = e.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(this.MotionHighlightView); } } } break; } } switch (e.Action) { case MotionEventActions.Up: { this.Center(true, true); break; } case MotionEventActions.Move: { if (this.GetScale() == 1f) { Center(true, true); } break; } } return(true); }