feat: 新增护眼距离和行走抖动检测提醒功能
This commit is contained in:
95
app/src/main/java/com/aoleyun/sn/view/FaceOverlayView.java
Normal file
95
app/src/main/java/com/aoleyun/sn/view/FaceOverlayView.java
Normal file
@@ -0,0 +1,95 @@
|
||||
package com.aoleyun.sn.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class FaceOverlayView extends View {
|
||||
private Paint pointPaint;
|
||||
private Paint textPaint;
|
||||
private PointF leftEye;
|
||||
private PointF rightEye;
|
||||
private double distance;
|
||||
private int imageWidth;
|
||||
private int imageHeight;
|
||||
|
||||
public FaceOverlayView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public FaceOverlayView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
pointPaint = new Paint();
|
||||
pointPaint.setColor(Color.RED);
|
||||
pointPaint.setStyle(Paint.Style.FILL);
|
||||
pointPaint.setStrokeWidth(10f);
|
||||
|
||||
textPaint = new Paint();
|
||||
textPaint.setColor(Color.YELLOW);
|
||||
textPaint.setTextSize(60f);
|
||||
textPaint.setFakeBoldText(true);
|
||||
textPaint.setShadowLayer(5, 0, 0, Color.BLACK);
|
||||
}
|
||||
|
||||
public void updateData(double distance, PointF leftEye, PointF rightEye, int imageWidth, int imageHeight) {
|
||||
this.distance = distance;
|
||||
this.leftEye = leftEye;
|
||||
this.rightEye = rightEye;
|
||||
this.imageWidth = imageWidth;
|
||||
this.imageHeight = imageHeight;
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (leftEye == null || rightEye == null || imageWidth <= 0 || imageHeight <= 0) {
|
||||
canvas.drawText("未检测到人脸", 50, 100, textPaint);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 获取 View 的尺寸
|
||||
float viewWidth = getWidth();
|
||||
float viewHeight = getHeight();
|
||||
|
||||
// 2. 计算缩放比例 (适配 PreviewView 的 FILL_CENTER 逻辑)
|
||||
// FILL_CENTER:取宽高缩放比例中较大的一个,使图像填满 View 且不拉伸,多出的部分被裁剪
|
||||
float scale = Math.max(viewWidth / imageWidth, viewHeight / imageHeight);
|
||||
|
||||
// 3. 计算偏移量(由居中裁剪产生)
|
||||
float postScaleWidth = imageWidth * scale;
|
||||
float postScaleHeight = imageHeight * scale;
|
||||
float offsetX = (viewWidth - postScaleWidth) / 2f;
|
||||
float offsetY = (viewHeight - postScaleHeight) / 2f;
|
||||
|
||||
// 4. 坐标映射并处理镜像
|
||||
// CameraX 的 PreviewView 显示前置摄像头时默认是镜像的
|
||||
// 映射公式: viewX = viewWidth - (imageX * scale + offsetX)
|
||||
float lx = viewWidth - (leftEye.x * scale + offsetX);
|
||||
float ly = leftEye.y * scale + offsetY;
|
||||
float rx = viewWidth - (rightEye.x * scale + offsetX);
|
||||
float ry = rightEye.y * scale + offsetY;
|
||||
|
||||
// 绘制眼睛点位
|
||||
canvas.drawCircle(lx, ly, 15, pointPaint);
|
||||
canvas.drawCircle(rx, ry, 15, pointPaint);
|
||||
|
||||
// 绘制连线,更直观
|
||||
canvas.drawLine(lx, ly, rx, ry, pointPaint);
|
||||
|
||||
canvas.drawText(String.format(Locale.getDefault(), "瞳距: %.2f", distance), 50, 100, textPaint);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user