// Scale the image down for faster face detection. private Bitmap PrepareBitmap() { EmCropImage eci = this.ECI; if (eci == null) { return(null); } if (eci.Bitmap == null || eci.Bitmap.IsRecycled) { return(null); } // 256 pixels wide is enough. if (eci.Bitmap.Width > 256) { this.Scale = 256.0F / eci.Bitmap.Width; } Matrix matrix = new Matrix(); matrix.SetScale(this.Scale, this.Scale); Bitmap faceBitmap = Bitmap.CreateBitmap(eci.Bitmap, 0, 0, eci.Bitmap .Width, eci.Bitmap.Height, matrix, true); return(faceBitmap); }
// 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); }
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 Run() { EmCropImage eci = this.ECI; if (eci == null) { return; } CountDownLatch latch = new CountDownLatch(1); Bitmap b = (eci.Image != null) ? eci.Image.FullSizeBitmap(IImageConstants.Unconstrained, 1024 * 1024) : eci.Bitmap; eci.MHandler.Post(() => { if (b != eci.Bitmap && b != null) { eci.ImageView.SetImageBitmapResetBase(b, true); eci.Bitmap.Recycle(); eci.Bitmap = b; } if (eci.ImageView.GetScale() == 1F) { eci.ImageView.Center(true, true); } latch.CountDown(); }); try { latch.Await(); } catch (InterruptedException e) { throw new RuntimeException(e); } eci.FaceDetectionRunnable.Run(); }
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); }
public EmCropRunnable(EmCropImage parent) { this.ECI = parent; }
public EmFaceDetectionRunnable(EmCropImage parent) { this.ECI = parent; }
public void Run() { EmCropImage eci = this.ECI; if (eci == null) { return; } this.MImageMatrix = eci.ImageView.ImageMatrix; Bitmap faceBitmap = PrepareBitmap(); if (faceBitmap != null) { this.Scale = 1.0F / this.Scale; if (faceBitmap != null && eci.DoingFaceDetection) { FaceDetector detector = new FaceDetector(faceBitmap.Width, faceBitmap.Height, this.Faces.Length); this.NumberOfFaces = detector.FindFaces(faceBitmap, this.Faces); } if (faceBitmap != null && faceBitmap != eci.Bitmap) { faceBitmap.Recycle(); } } eci.MHandler.Post(() => { eci.WaitingToPick = this.NumberOfFaces > 1; if (this.NumberOfFaces > 0) { for (int i = 0; i < this.NumberOfFaces; i++) { HandleFace(this.Faces[i]); } } else { MakeDefault(); } eci.ImageView.Invalidate(); if (eci.ImageView.MotionHighlightViews.Count == 1) { eci.MCrop = eci.ImageView.MotionHighlightViews [0]; eci.MCrop.Focused = true; } // Translation Note: I have no idea how to get to this area of code. // It has something to do with face recognition. if (this.NumberOfFaces > 1) { Toast t = Toast.MakeText(eci, "Touch a face to begin.", ToastLength.Short); t.Show(); } }); }