Files
CubeAoleyunSN/app/src/main/java/com/aoleyun/sn/view/FaceOverlayView.java

96 lines
3.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}