优化人脸识别显示形状
This commit is contained in:
@@ -905,62 +905,11 @@ class MainScreenPresentation(
|
||||
displayOrientation: Int,
|
||||
scale: Float
|
||||
): ViewGroup.LayoutParams {
|
||||
// val layoutParams = previewView.layoutParams
|
||||
// val measuredWidth = previewView.measuredWidth
|
||||
// val measuredHeight = previewView.measuredHeight
|
||||
// var ratio = (previewSize.height.toFloat()) / previewSize.width.toFloat()
|
||||
// if (ratio > 1) {
|
||||
// ratio = 1 / ratio
|
||||
// }
|
||||
// if (displayOrientation % 180 == 0) {
|
||||
// layoutParams.width = measuredWidth
|
||||
// layoutParams.height = (measuredWidth * ratio).toInt()
|
||||
// } else {
|
||||
// layoutParams.height = measuredHeight
|
||||
// layoutParams.width = (measuredHeight * ratio).toInt()
|
||||
// }
|
||||
// if (scale < 1f) {
|
||||
// val rgbParam = rgbPreview.layoutParams
|
||||
// layoutParams.width = (rgbParam.width * scale).toInt()
|
||||
// layoutParams.height = (rgbParam.height * scale).toInt()
|
||||
// } else {
|
||||
// layoutParams.width = (layoutParams.width * scale).toInt()
|
||||
// layoutParams.height = (layoutParams.height * scale).toInt()
|
||||
// }
|
||||
//
|
||||
// val metrics = DisplayMetrics()
|
||||
// activity.windowManager.defaultDisplay.getMetrics(metrics)
|
||||
//
|
||||
// if (layoutParams.width >= metrics.widthPixels) {
|
||||
// val viewRatio = layoutParams.width / (metrics.widthPixels.toFloat())
|
||||
// layoutParams.width = (layoutParams.width / viewRatio).toInt()
|
||||
// layoutParams.height = (layoutParams.height / viewRatio).toInt()
|
||||
// }
|
||||
// if (layoutParams.height >= metrics.heightPixels) {
|
||||
// val viewRatio = layoutParams.height / (metrics.heightPixels.toFloat())
|
||||
// layoutParams.width = (layoutParams.width / viewRatio).toInt()
|
||||
// layoutParams.height = (layoutParams.height / viewRatio).toInt()
|
||||
// }
|
||||
|
||||
// Timber.tag(TAG).d("initRgbCamera:metrics(${metrics.widthPixels},${metrics.heightPixels})")
|
||||
|
||||
|
||||
//val layoutParams = previewView.layoutParams
|
||||
//layoutParams.width = 1024
|
||||
//layoutParams.height = 768
|
||||
// val w = 600.dp //(912.dp * scale).toInt()
|
||||
// val h = 900.dp //684.dp
|
||||
// val w = 500.dp
|
||||
// val h = 850.dp
|
||||
val w = 600.dp
|
||||
val h = 1068.dp
|
||||
//(1024*scale).toInt()
|
||||
val layoutParams = FrameLayout.LayoutParams(w, h);
|
||||
// val layoutParams = FrameLayout.LayoutParams(480, 320);
|
||||
// val layoutParams = FrameLayout.LayoutParams(912.dp, 684.dp);
|
||||
previewView.setLayoutParams(layoutParams)
|
||||
faceRectView.setLayoutParams(layoutParams)
|
||||
|
||||
return layoutParams
|
||||
}
|
||||
|
||||
|
||||
@@ -280,58 +280,9 @@ class FacePayPresentation(
|
||||
displayOrientation: Int,
|
||||
scale: Float
|
||||
): ViewGroup.LayoutParams {
|
||||
// val layoutParams = previewView.layoutParams
|
||||
// val measuredWidth = previewView.measuredWidth
|
||||
// val measuredHeight = previewView.measuredHeight
|
||||
// var ratio = (previewSize.height.toFloat()) / previewSize.width.toFloat()
|
||||
// if (ratio > 1) {
|
||||
// ratio = 1 / ratio
|
||||
// }
|
||||
// if (displayOrientation % 180 == 0) {
|
||||
// layoutParams.width = measuredWidth
|
||||
// layoutParams.height = (measuredWidth * ratio).toInt()
|
||||
// } else {
|
||||
// layoutParams.height = measuredHeight
|
||||
// layoutParams.width = (measuredHeight * ratio).toInt()
|
||||
// }
|
||||
// if (scale < 1f) {
|
||||
// val rgbParam = rgbPreview.getLayoutParams()
|
||||
// layoutParams.width = (rgbParam.width * scale).toInt()
|
||||
// layoutParams.height = (rgbParam.height * scale).toInt()
|
||||
// } else {
|
||||
// layoutParams.width = (layoutParams.width * scale).toInt()
|
||||
// layoutParams.height = (layoutParams.height * scale).toInt()
|
||||
// }
|
||||
//
|
||||
// val metrics = DisplayMetrics()
|
||||
// activity.windowManager.defaultDisplay.getMetrics(metrics)
|
||||
//
|
||||
// if (layoutParams.width >= metrics.widthPixels) {
|
||||
// val viewRatio = layoutParams.width / (metrics.widthPixels.toFloat())
|
||||
// layoutParams.width = (layoutParams.width / viewRatio).toInt()
|
||||
// layoutParams.height = (layoutParams.height / viewRatio).toInt()
|
||||
// }
|
||||
// if (layoutParams.height >= metrics.heightPixels) {
|
||||
// val viewRatio = layoutParams.height / (metrics.heightPixels.toFloat())
|
||||
// layoutParams.width = (layoutParams.width / viewRatio).toInt()
|
||||
// layoutParams.height = (layoutParams.height / viewRatio).toInt()
|
||||
// }
|
||||
|
||||
|
||||
// val layoutParams = previewView.layoutParams
|
||||
// layoutParams.width = (608.dp * 1.5).roundToInt()
|
||||
// layoutParams.height = (456.dp * 1.5).roundToInt()
|
||||
// layoutParams.width = (608.dp * 1.5).roundToInt()
|
||||
// layoutParams.height = (456.dp * 1.5).roundToInt()
|
||||
// layoutParams.width = 1024
|
||||
// layoutParams.height = 768
|
||||
// val w = 500.dp
|
||||
// val h = 850.dp
|
||||
val w = 600.dp
|
||||
val w = (600.dp * 1.5).toInt()
|
||||
val h = 1068.dp
|
||||
// val w = 720.dp
|
||||
// val h = 1280.dp
|
||||
val layoutParams = FrameLayout.LayoutParams(w, h);
|
||||
val layoutParams = FrameLayout.LayoutParams(w, h)
|
||||
|
||||
previewView.setLayoutParams(layoutParams)
|
||||
faceRectView.setLayoutParams(layoutParams)
|
||||
@@ -472,9 +423,10 @@ class FacePayPresentation(
|
||||
)
|
||||
|
||||
irFaceRectTransformer = FaceRectTransformer(
|
||||
// previewSizeIr.width, previewSizeIr.height,
|
||||
previewSizeIr.width, previewSizeIr.height,
|
||||
// layoutParams.width, layoutParams.height,
|
||||
layoutParams.width, layoutParams.height,
|
||||
layoutParams.width, layoutParams.height, displayOrientation, cameraId, isMirror,
|
||||
displayOrientation, cameraId, isMirror,
|
||||
ConfigUtil.isDrawIrRectHorizontalMirror(context),
|
||||
ConfigUtil.isDrawIrRectVerticalMirror(context)
|
||||
)
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.sw.dualscreen.view
|
||||
|
||||
import androidx.core.graphics.toColorInt
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
|
||||
/**
|
||||
* 带镂空椭圆的矩形自定义View
|
||||
* 矩形尺寸:400dp × 510dp,背景色 #FFF4FAFF
|
||||
* 镂空椭圆尺寸:400dp × 436dp,居中显示
|
||||
*/
|
||||
class HollowOvalInRectView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : View(context, attrs, defStyleAttr) {
|
||||
|
||||
// 基础尺寸配置(dp)
|
||||
private val rectWidthDp = 400f // 矩形宽度
|
||||
private val rectHeightDp = 510f // 矩形高度
|
||||
private val ovalWidthDp = 400f // 椭圆宽度
|
||||
private val ovalHeightDp = 436f // 椭圆高度
|
||||
|
||||
// 转换后的像素尺寸
|
||||
private val rectWidth: Float
|
||||
private val rectHeight: Float
|
||||
private var ovalWidth: Float
|
||||
private var ovalHeight: Float
|
||||
|
||||
// 矩形背景画笔(颜色 #FFF4FAFF)
|
||||
private val rectPaint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
color = "#FFF4FAFF".toColorInt() // 矩形背景色
|
||||
// color = "#FFFFFF".toColorInt() // 矩形背景色
|
||||
style = Paint.Style.FILL
|
||||
}
|
||||
|
||||
// 镂空椭圆画笔(核心:DST_OUT模式实现镂空)
|
||||
private val hollowOvalPaint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
color = Color.BLACK // 颜色不影响镂空效果,仅需非透明即可
|
||||
style = Paint.Style.FILL
|
||||
xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT)
|
||||
}
|
||||
|
||||
// 椭圆路径(复用避免重复创建)
|
||||
private val ovalPath = Path()
|
||||
|
||||
init {
|
||||
// dp转px,保证多设备尺寸一致
|
||||
val density = resources.displayMetrics.density
|
||||
rectWidth = rectWidthDp * density
|
||||
rectHeight = rectHeightDp * density
|
||||
ovalWidth = ovalWidthDp * density
|
||||
ovalHeight = ovalHeightDp * density
|
||||
|
||||
// 关键配置:关闭硬件加速保证Xfermode生效
|
||||
setLayerType(LAYER_TYPE_HARDWARE, null)
|
||||
// 视图背景透明,避免干扰
|
||||
setBackgroundColor(Color.TRANSPARENT)
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制设置View尺寸为指定的矩形尺寸
|
||||
*/
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
val targetWidth = MeasureSpec.makeMeasureSpec(rectWidth.toInt(), MeasureSpec.EXACTLY)
|
||||
val targetHeight = MeasureSpec.makeMeasureSpec(rectHeight.toInt(), MeasureSpec.EXACTLY)
|
||||
super.onMeasure(targetWidth, targetHeight)
|
||||
}
|
||||
|
||||
/**
|
||||
* 核心绘制逻辑:先画矩形,再画镂空椭圆
|
||||
*/
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
|
||||
// 保存画布图层,确保Xfermode生效
|
||||
val layerId = canvas.saveLayer(0f, 0f, width.toFloat(), height.toFloat(), null)
|
||||
|
||||
// 1. 绘制底层矩形(背景色 #FFF4FAFF)
|
||||
canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), rectPaint)
|
||||
|
||||
// 2. 计算椭圆居中坐标(椭圆宽度和矩形宽度一致,仅垂直居中)
|
||||
val ovalTop = (rectHeight - ovalHeight) / 2 // 椭圆顶部偏移
|
||||
val ovalBottom = ovalTop + ovalHeight // 椭圆底部坐标
|
||||
|
||||
// 3. 绘制镂空椭圆(居中)
|
||||
ovalPath.reset()
|
||||
ovalPath.addOval(
|
||||
0f, // 左:和矩形左对齐(宽度一致)
|
||||
ovalTop, // 上:垂直居中
|
||||
rectWidth, // 右:和矩形右对齐
|
||||
ovalBottom, // 下
|
||||
Path.Direction.CW
|
||||
)
|
||||
canvas.drawPath(ovalPath, hollowOvalPaint)
|
||||
|
||||
// 恢复画布状态
|
||||
canvas.restoreToCount(layerId)
|
||||
}
|
||||
|
||||
// 扩展方法:支持动态修改矩形背景色
|
||||
fun updateRectBackgroundColor(colorHex: String) {
|
||||
try {
|
||||
rectPaint.color = Color.parseColor(colorHex)
|
||||
invalidate() // 重绘视图
|
||||
} catch (e: IllegalArgumentException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
// 扩展方法:支持动态修改椭圆尺寸(可选)
|
||||
fun updateOvalSize(widthDp: Float, heightDp: Float) {
|
||||
val density = resources.displayMetrics.density
|
||||
ovalWidth = widthDp * density
|
||||
ovalHeight = heightDp * density
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="510dp">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flFace"
|
||||
@@ -89,33 +89,9 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<!-- <ImageView-->
|
||||
<!-- android:id="@+id/ivPreviewImage"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent" />-->
|
||||
<!-- <ImageView-->
|
||||
<!-- android:id="@+id/ivFaceRecMask"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_gravity="bottom"-->
|
||||
<!-- android:adjustViewBounds="true"-->
|
||||
<!-- android:src="@drawable/face_mask"-->
|
||||
<!-- android:visibility="visible" />-->
|
||||
|
||||
<!-- <TextView-->
|
||||
<!-- android:id="@+id/tvFaceTip"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_gravity="bottom|center"-->
|
||||
<!-- android:layout_marginBottom="56dp"-->
|
||||
<!-- android:text="请正视屏幕进行面部识别..."-->
|
||||
<!-- android:textColor="@color/white"-->
|
||||
<!-- android:textSize="24sp"-->
|
||||
<!-- android:visibility="v" />-->
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fl_recognize_ir"
|
||||
android:layout_width="1.3333dp"
|
||||
android:id="@+id/flRecognizeIr"
|
||||
android:layout_width="1.33dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:visibility="visible">
|
||||
@@ -149,7 +125,7 @@
|
||||
android:layout_weight="1"
|
||||
android:background="#FFF4FAFF" />
|
||||
|
||||
<com.sw.dualscreen.view.HollowCircleRectView
|
||||
<com.sw.dualscreen.view.HollowOvalInRectView
|
||||
android:layout_width="400dp"
|
||||
android:layout_height="510dp"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
@@ -165,7 +141,6 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="55dp"
|
||||
android:text="请正视屏幕进行面部识别..."
|
||||
android:textColor="#ff5e7585"
|
||||
android:textSize="22sp"
|
||||
@@ -173,21 +148,12 @@
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
tools:ignore="HardcodedText" />
|
||||
</FrameLayout>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="85dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="#FFF4FAFF"/>
|
||||
<!-- <View-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="85dp"-->
|
||||
<!-- android:layout_gravity="bottom"-->
|
||||
<!-- android:background="#FFF4FAFF"/>-->
|
||||
</FrameLayout>
|
||||
<!-- <TextView-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginTop="55dp"-->
|
||||
<!-- android:text="请正视屏幕进行面部识别..."-->
|
||||
<!-- android:textColor="#ff5e7585"-->
|
||||
<!-- android:textSize="22sp"-->
|
||||
<!-- android:textStyle="bold"-->
|
||||
<!-- tools:ignore="HardcodedText" />-->
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -72,23 +72,6 @@
|
||||
android:src="@drawable/face_mask"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!-- <TextView-->
|
||||
<!-- android:id="@+id/tvFaceTip"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_gravity="bottom|center"-->
|
||||
<!-- android:layout_marginBottom="56dp"-->
|
||||
<!-- android:text="请正视屏幕进行面部识别..."-->
|
||||
<!-- android:textColor="@color/white"-->
|
||||
<!-- android:textSize="22sp"-->
|
||||
<!-- android:visibility="gone" />-->
|
||||
|
||||
<!-- <ImageView-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent"-->
|
||||
<!-- android:layout_margin="28dp"-->
|
||||
<!-- android:background="@drawable/ic_camera_rect" />-->
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
@@ -108,7 +91,7 @@
|
||||
android:layout_weight="1"
|
||||
android:background="#FFF4FAFF" />
|
||||
|
||||
<com.sw.dualscreen.view.HollowCircleRectView
|
||||
<com.sw.dualscreen.view.HollowOvalInRectView
|
||||
android:layout_width="400dp"
|
||||
android:layout_height="510dp"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
@@ -121,22 +104,15 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- <ImageView-->
|
||||
<!-- android:layout_width="400dp"-->
|
||||
<!-- android:layout_height="400dp"-->
|
||||
<!-- android:layout_marginTop="55dp"-->
|
||||
<!-- android:layout_gravity="center_horizontal"-->
|
||||
<!-- android:src="@drawable/facewrap"/>-->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvFaceTip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:text="请正视屏幕进行面部识别..."
|
||||
android:textColor="#FF0A1428"
|
||||
android:textSize="22sp" />
|
||||
android:textSize="22sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
</FrameLayout>
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
@@ -316,4 +292,9 @@
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!-- <ImageView-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent"-->
|
||||
<!-- android:src="@drawable/bg_face"/>-->
|
||||
|
||||
</FrameLayout>
|
||||
Reference in New Issue
Block a user