void HAL.Pixel(float x, float y, float r, float g, float b) { var x1 = Clamp(x, frameWidth); var y1 = Clamp(y, frameHeight); int r1 = Clamp(r, 256); int g1 = Clamp(g, 256); int b1 = Clamp(b, 256); paint.setColor((0xFF << 24) | (r1 << 16) | (g1 << 8) | b1); frameCanvas.drawPoint(x1, y1, paint); int Clamp(float a, int b) => System.Math.Min(System.Math.Max((int)(a * b), 0), b - 1); }
protected internal override void onDraw(Canvas canvas) { if (mFaces != null && mZoomRect != null) { // Prepare matrix mMatrix.reset(); mAspectRatio.reset(); mActualRect.set(0, 0, mPreviewSize.Width, mPreviewSize.Height); // First apply zoom (crop) rect. // Unlike the documentation, many device does not report final crop region. // So, here we calculate final crop region which takes account aspect ratio between crop region and preview size. { mRevisionZoomRect.set(mZoomRect); float left = mRevisionZoomRect.left; float top = mRevisionZoomRect.top; mRevisionZoomRect.offsetTo(0, 0); mAspectRatio.setRectToRect(mActualRect, mRevisionZoomRect, Matrix.ScaleToFit.CENTER); mAspectRatio.mapRect(mActualRect); mActualRect.offset(left, top); } mMatrix.postTranslate(-mActualRect.centerX(), -mActualRect.centerY()); // compensate mirror mMatrix.postScale(mFacing == SCameraCharacteristics.LENS_FACING_FRONT ? -1 : 1, 1); // Then rotate and scale to UI size mMatrix.postRotate(mRotation); if (mOrientation == Configuration.ORIENTATION_LANDSCAPE) { mMatrix.postScale((float)Width / mActualRect.width(), (float)Height / mActualRect.height()); } else { mMatrix.postScale((float)Height / mActualRect.width(), (float)Width / mActualRect.height()); } mMatrix.postTranslate((float)Width / 2, (float)Height / 2); foreach (Face face in mFaces) { mBoundRect.set(face.Bounds); mMatrix.mapRect(mBoundRect); mPaint.Color = Color.BLUE; mPaint.StrokeWidth = 3; canvas.drawRect(mBoundRect, mPaint); { // Additional features may not supported. float[] point = new float[2]; mPaint.Color = Color.RED; mPaint.StrokeWidth = 10; if (face.LeftEyePosition != null) { mMatrix.mapPoints(point, new float[] { face.LeftEyePosition.x, face.LeftEyePosition.y }); canvas.drawPoint(point[0], point[1], mPaint); } if (face.RightEyePosition != null) { mMatrix.mapPoints(point, new float[] { face.RightEyePosition.x, face.RightEyePosition.y }); canvas.drawPoint(point[0], point[1], mPaint); } if (face.MouthPosition != null) { mMatrix.mapPoints(point, new float[] { face.MouthPosition.x, face.MouthPosition.y }); canvas.drawPoint(point[0], point[1], mPaint); } mPaint.Color = Color.YELLOW; mPaint.StrokeWidth = 3; mPaint.TextSize = 30; if (face.Id != Face.ID_UNSUPPORTED) { canvas.drawText(string.Format("ID:{0:D}, Score:{1:D}", face.Id, face.Score), mBoundRect.left, mBoundRect.top, mPaint); } else { canvas.drawText(string.Format("Score:{0:D}", face.Score), mBoundRect.left, mBoundRect.top, mPaint); } } } } }
protected internal override void onDraw(Canvas canvas) { if (mFaces != null && mZoomRect != null) { // Prepare matrix mMatrix.reset(); mAspectRatio.reset(); mActualRect.set(0, 0, mPreviewSize.Width, mPreviewSize.Height); // First apply zoom (crop) rect. // Unlike the documentation, many device does not report final crop region. // So, here we calculate final crop region which takes account aspect ratio between crop region and preview size. { mRevisionZoomRect.set(mZoomRect); float left = mRevisionZoomRect.left; float top = mRevisionZoomRect.top; mRevisionZoomRect.offsetTo(0, 0); mAspectRatio.setRectToRect(mActualRect, mRevisionZoomRect, Matrix.ScaleToFit.CENTER); mAspectRatio.mapRect(mActualRect); mActualRect.offset(left, top); } mMatrix.postTranslate(-mActualRect.centerX(), -mActualRect.centerY()); // compensate mirror mMatrix.postScale(mFacing == SCameraCharacteristics.LENS_FACING_FRONT ? - 1 : 1, 1); // Then rotate and scale to UI size mMatrix.postRotate(mRotation); if (mOrientation == Configuration.ORIENTATION_LANDSCAPE) { mMatrix.postScale((float) Width / mActualRect.width(), (float) Height / mActualRect.height()); } else { mMatrix.postScale((float) Height / mActualRect.width(), (float) Width / mActualRect.height()); } mMatrix.postTranslate((float)Width / 2, (float)Height / 2); foreach (Face face in mFaces) { mBoundRect.set(face.Bounds); mMatrix.mapRect(mBoundRect); mPaint.Color = Color.BLUE; mPaint.StrokeWidth = 3; canvas.drawRect(mBoundRect, mPaint); { // Additional features may not supported. float[] point = new float[2]; mPaint.Color = Color.RED; mPaint.StrokeWidth = 10; if (face.LeftEyePosition != null) { mMatrix.mapPoints(point, new float[]{face.LeftEyePosition.x, face.LeftEyePosition.y}); canvas.drawPoint(point[0], point[1], mPaint); } if (face.RightEyePosition != null) { mMatrix.mapPoints(point, new float[]{face.RightEyePosition.x, face.RightEyePosition.y}); canvas.drawPoint(point[0], point[1], mPaint); } if (face.MouthPosition != null) { mMatrix.mapPoints(point, new float[]{face.MouthPosition.x, face.MouthPosition.y}); canvas.drawPoint(point[0], point[1], mPaint); } mPaint.Color = Color.YELLOW; mPaint.StrokeWidth = 3; mPaint.TextSize = 30; if (face.Id != Face.ID_UNSUPPORTED) { canvas.drawText(string.Format("ID:{0:D}, Score:{1:D}", face.Id, face.Score), mBoundRect.left, mBoundRect.top, mPaint); } else { canvas.drawText(string.Format("Score:{0:D}", face.Score), mBoundRect.left, mBoundRect.top, mPaint); } } } } }