feat: 新增护眼距离和行走抖动检测提醒功能

This commit is contained in:
2026-07-30 09:36:10 +08:00
parent 132000b4e1
commit 621ebd64d7
25 changed files with 2112 additions and 76 deletions

View 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);
}
}