Browse Source

:seedling: 整合人脸SDK

everywindchase 9 months ago
parent
commit
77c93c4bea

+ 2 - 2
app/src/main/java/com/ethan/psbc/managers/impls/retrofit/INetworkMain.kt

@@ -121,8 +121,8 @@ interface INetworkMain {
     fun userFaceStoreList(@Query("id") id:Int):Single<UserFaceStoreListResp>
 
     @Streaming
-   @GET(value = "{imageUrl}")
-    fun userFaceImage(@Path(value = "imageUrl", encoded = true) imageUrl:String):Call<ResponseBody>
+   @GET
+    fun userFaceImage(@Url  imageUrl:String):Call<ResponseBody>
 
 
 

+ 77 - 22
app/src/main/java/com/ethan/psbc/ui/dialogs/DialogValidateFace.kt

@@ -36,12 +36,9 @@ import io.reactivex.rxjava3.observers.DisposableSingleObserver
 import io.reactivex.rxjava3.schedulers.Schedulers
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
-import okhttp3.ResponseBody
 import org.koin.core.component.get
 import org.koin.core.component.inject
-import retrofit2.Call
-import retrofit2.Callback
-import retrofit2.Response
+import java.io.ByteArrayOutputStream
 import java.io.File
 import java.nio.ByteBuffer
 import java.util.*
@@ -85,7 +82,7 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), IV
         this.faceHandleRet=faceHandleRet
         mBinding.mPreviewView.scaleType=PreviewView.ScaleType.FIT_CENTER
         runCamera(this, mBinding.mPreviewView, faceHandleRet, context = context)
-        mBinding.mPreviewView.bringToFront()
+        //mBinding.mPreviewView.bringToFront()
         mBinding.takePhoto.setOnClickListener(this)
     }
 
@@ -314,19 +311,85 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), IV
                                         override fun onSuccess(t: INetworkMain.UserFaceStoreListResp) {
                                             var   registryImgUrl= t.rows.get(0).alignedpic
                                             if(registryImgUrl.isNotEmpty()){
-                                               var  respCall= get<INetworkMain>().userFaceImage(registryImgUrl.substring(1,registryImgUrl.length))
-                                                respCall.enqueue(object:Callback<ResponseBody>{
-                                                    override fun onResponse(p0: Call<ResponseBody>, p1: Response<ResponseBody>) {
+                                               var  respCall= get<INetworkMain>().userFaceImage(registryImgUrl).execute()
+
+
+                                                var    registerData:ByteArray?=null
+                                                if(null!=respCall.body()) {
+                                                    var bos: ByteArrayOutputStream? =null
+                                                    try{
+                                                        bos=ByteArrayOutputStream()
+                                                        val   ins= respCall.body()!!.byteStream()
+                                                        val byteArray= ByteArray(1024)
+                                                        var len:Int
+                                                        while(((ins.read(byteArray)).also{ len=it})!=-1){
+                                                                bos.write(byteArray,0,len)
+                                                        }
+
+                                                    }catch (e:Exception){
+                                                        //ignore
+                                                        registerData=ByteArray(0)
+                                                    }finally {
+                                                        bos?.close()
+                                                    }
+
+                                                    if (bos != null) {
+                                                        registerData=  bos.toByteArray()
+                                                    }else{
+                                                        registerData=ByteArray(0)
+                                                    }
+
+
+                                                }
+
+
+
+
+
+
 
-                                                        FaceRecog.cwComputeMatchScore(handle,btFeature, p1.body()?.bytes(),1,scores)
-                                                        Log.d("demo", "检测到相似度为:${scores[0]}" )
+
+                                                if(null!=registerData) {
+
+                                                    try{
+                                                        var dFaceBuffer=Array(1){_ ->FaceInfo()}
+                                                        var dres=FaceDetTrack.cwFaceDetection(handle, registerData,640, 480, FaceInterface.cw_img_form_t.CW_IMAGE_BINARY ,  0, 0, 	FaceInterface.cw_op_t.CW_OP_ALL , dFaceBuffer)
+
+                                                        if (dres >= FaceInterface.cw_errcode_t.CW_UNKNOWN_ERR) {
+                                                            scores[0]=0.0F
+                                                            Log.d("demo", "检测到相似度为:${scores[0]}")
+                                                        }else   if(dres>1){
+                                                            scores[0]=0.0F
+                                                            Log.d("demo", "检测到相似度为:${scores[0]}")
+                                                        }else{
+                                                            val dtFeature=ByteArray(iFeaLen)
+                                                            FaceRecog.cwGetFaceFeature(handle,dFaceBuffer[0].alignedData,dFaceBuffer[0].alignedW,
+                                                                dFaceBuffer[0].alignedH,dFaceBuffer[0].nChannels, dtFeature)
+                                                            FaceRecog.cwComputeMatchScore(handle, btFeature, dtFeature, 1, scores)
+                                                            Log.d("demo", "检测到相似度为:${scores[0]}")
+                                                        }
+                                                    }catch (e:Exception){
+                                                        scores[0]=0.0F
+                                                        Log.d("demo", "人脸对比异常:${e.message}")
+                                                        Log.d("demo", "检测到相似度为:${scores[0]}")
                                                     }
 
-                                                    override fun onFailure(p0: Call<ResponseBody>, p1: Throwable) {
-                                                        Log.d("demo", "请求id为0的客户人脸信息二进制错误:${p1.message}" )
+
+                                                } else{
+                                                            scores[0]=0.0F
+                                                            Log.d("demo", "检测到相似度为:${scores[0]}")
+                                                 }
+
+
+
+                                                context.lifecycleScope.launch {
+                                                    if(scores.isNotEmpty() && scores[0] > 0.750000) {
+                                                        Toast.makeText(context, "检测到人脸:${faceDetRet},是同一个人", Toast.LENGTH_SHORT).show()
+                                                    }else{
+                                                        Toast.makeText(context, "检测到人脸:${faceDetRet},不是同一个人", Toast.LENGTH_SHORT).show()
                                                     }
+                                                }
 
-                                                })
                                             }
 
 
@@ -346,13 +409,7 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), IV
 
 
 
-                                context.lifecycleScope.launch {
-                                   if(scores.isNotEmpty() && scores[0] > 0.750000) {
-                                       Toast.makeText(context, "检测到人脸:${faceDetRet},是同一个人", Toast.LENGTH_SHORT).show()
-                                   }else{
-                                       Toast.makeText(context, "检测到人脸:${faceDetRet},不是同一个人", Toast.LENGTH_SHORT).show()
-                                   }
-                                }
+
 
 
                             }
@@ -472,9 +529,7 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), IV
         result.addListener({
             try {
                 if (result.get().isFocusSuccessful) {
-                    mBinding.focusView.showFocusView(x.toInt(),y.toInt())
                     Log.d("demo", "聚集成功")
-
                 } else {
                     Log.d("demo", "聚集失败")
                 }

+ 0 - 125
app/src/main/java/com/ethan/psbc/ui/widget/CameraFocusView.kt

@@ -1,125 +0,0 @@
-package com.ethan.psbc.ui.widget
-
-import android.content.Context
-import android.graphics.Canvas
-import android.graphics.Color
-import android.graphics.Paint
-import android.graphics.RectF
-import android.os.Handler
-import android.util.AttributeSet
-import android.util.TypedValue
-import android.view.View
-import androidx.constraintlayout.widget.ConstraintLayout
-import com.qmuiteam.qmui.util.QMUIDisplayHelper.getDisplayMetrics
-
-
-class CameraFocusView(context: Context?,attrs: AttributeSet?) : View(context,attrs) {
-
-    private var focusSize = 0 //焦点框的大小
-    private var focusColor = 0 //焦点框的颜色
-    private var focusTime = 0 //焦点框显示的时长
-    private var focusStrokeSize = 0 //焦点框线条的尺寸
-    private var cornerSize = 0 //焦点框圆角尺寸
-    private var handler: Handler? = null
-    private var runnable: Runnable? = null
-    private var mPaint: Paint? = null
-    private var rect: RectF? = null
-
-
-
-    init {
-        if (context != null) {
-            init(context)
-        }
-}
-
-
-
-
-
-
-    private fun init(context: Context) {
-        handler = Handler()
-        mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
-        rect = RectF()
-        runnable = Runnable {
-            hideFocusView()
-        }
-    }
-
-    fun setParam(
-        focusViewSize: Int, focusViewColor: Int, focusViewTime: Int,
-        focusViewStrokeSize: Int, cornerViewSize: Int
-    ) {
-        if (focusViewSize == -1) {
-            this.focusSize = dp2px(context, 60F)
-        } else {
-            this.focusSize = focusViewSize
-        }
-
-        if (focusViewColor == -1) {
-            this.focusColor = Color.GREEN
-        } else {
-            this.focusColor = focusViewColor
-        }
-        this.focusTime = focusViewTime
-
-        if (focusViewStrokeSize == -1) {
-            this.focusStrokeSize = dp2px(context, 2F)
-        } else {
-            this.focusStrokeSize = focusViewStrokeSize
-        }
-
-        if (cornerViewSize == -1) {
-            this.cornerSize = focusSize / 5
-        } else {
-            this.cornerSize = cornerViewSize
-        }
-
-        mPaint!!.style = Paint.Style.STROKE
-        mPaint!!.strokeWidth = focusStrokeSize.toFloat()
-        mPaint!!.color = focusColor
-        rect!!.top = 0f
-        rect!!.left = rect!!.top
-        rect!!.bottom = focusSize.toFloat()
-        rect!!.right = rect!!.bottom
-    }
-
-    fun showFocusView(x: Int, y: Int) {
-        visibility = VISIBLE
-        val layoutParams = layoutParams as ConstraintLayout.LayoutParams
-        layoutParams.leftMargin = x - focusSize / 2
-        layoutParams.topMargin = y - focusSize / 2
-        setLayoutParams(layoutParams)
-        invalidate()
-        runnable?.let { handler?.postDelayed(it, (focusTime * 1000).toLong()) }
-    }
-
-    fun hideFocusView() {
-        visibility = GONE
-        runnable?.let { handler?.removeCallbacks(it) }
-    }
-
-    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
-        setMeasuredDimension(focusSize, focusSize)
-    }
-
-    override fun onDraw(canvas: Canvas) {
-        super.onDraw(canvas)
-        canvas.drawRoundRect(rect!!, cornerSize.toFloat(), cornerSize.toFloat(), mPaint!!)
-    }
-
-    override fun onDetachedFromWindow() {
-        runnable?.let { handler?.removeCallbacks(it) }
-        super.onDetachedFromWindow()
-    }
-
-
-
-    fun dp2px(mContext:Context,   dipValue:Float) : Int {
-        return  TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, getDisplayMetrics(mContext)).toInt()
-    }
-
-
-
-}

+ 151 - 0
app/src/main/java/com/ethan/psbc/ui/widget/CircleProgressView.kt

@@ -0,0 +1,151 @@
+package com.ethan.psbc.ui.widget
+
+import android.content.Context
+import android.graphics.*
+import android.util.Log
+import android.view.View
+
+
+class CircleProgressView(context: Context) : View(context) {
+
+
+    private var bottomCirclePaint: Paint? = null //底部圆画笔
+    private var paintWidth = 0f //底部圆外扩半径
+    private var centerPoint: PointF? = null //中心点
+
+    private var mInnerPaint: Paint? = null //内环
+    private var mTextPaint: Paint? = null //文字
+    private var InnerRectF: RectF? = null //内环 位置
+
+    private var mProgressPaint: Paint? = null //内环 进度
+
+    private var progress = 0 //进度
+
+    private var progressStartColor = "#b3e6fe" //进度渐变开始颜色
+    private var progressEndColor = "#04adfb" //进度渐变结束颜色
+
+    fun setProgressStartColor(progressStartColor: String) {
+        this.progressStartColor = progressStartColor
+    }
+
+    fun setProgressEndColor(progressEndColor: String) {
+        this.progressEndColor = progressEndColor
+    }
+
+
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+    }
+
+    override fun onDraw(canvas: Canvas) {
+        super.onDraw(canvas)
+        initPaint()
+        var text = "未检测到人脸"
+        var angle = progress.toFloat() * 330 / 100
+        if (angle > 330) {
+            angle = 330f
+        } else if (angle > 30) {
+            text = "请保持不动"
+        }
+        val width = mTextPaint!!.measureText(text)
+
+        canvas.drawText(text, centerPoint!!.x - width / 2, InnerRectF!!.top + 100, mTextPaint!!)
+
+        canvas.drawCircle(centerPoint!!.x, centerPoint!!.y, (paintWidth * 3 / 2 + paintWidth / 2), bottomCirclePaint!!)
+        canvas.drawArc(InnerRectF!!, 105f, 330f, false, mInnerPaint!!)
+        canvas.drawArc(InnerRectF!!, 105f, angle, false, mProgressPaint!!)
+    }
+
+    /**
+     * 初始化画笔
+     */
+    private fun initPaint() {
+        if (bottomCirclePaint == null) {
+            bottomCirclePaint = Paint()
+            bottomCirclePaint!!.color = Color.WHITE
+            bottomCirclePaint!!.isAntiAlias = true //抗锯齿
+            bottomCirclePaint!!.style = Paint.Style.STROKE //不加这个不显示
+        }
+        if (mInnerPaint == null) {
+            mInnerPaint = Paint()
+            mInnerPaint!!.color = Color.GRAY
+            mInnerPaint!!.alpha = 60
+            //抗锯齿
+            mInnerPaint!!.isAntiAlias = true
+            //画笔宽度
+            mInnerPaint!!.strokeWidth = 12f
+            //防抖动
+            mInnerPaint!!.isDither = true
+            //设置状态
+            mInnerPaint!!.style = Paint.Style.STROKE
+            //头部小圆点
+            mInnerPaint!!.strokeCap = Paint.Cap.ROUND
+        }
+        if (mTextPaint == null) {
+            mTextPaint = Paint()
+            mTextPaint!!.color = Color.WHITE
+            mTextPaint!!.textSize = 38f
+        }
+        if (mProgressPaint == null) {
+            mProgressPaint = Paint()
+            mProgressPaint!!.color = Color.BLUE
+            //抗锯齿
+            mProgressPaint!!.isAntiAlias = true
+            //画笔宽度
+            mProgressPaint!!.strokeWidth = 12f
+            //防抖动
+            mProgressPaint!!.isDither = true
+            //设置状态
+            mProgressPaint!!.style = Paint.Style.STROKE
+            //头部小圆点
+            mProgressPaint!!.strokeCap = Paint.Cap.ROUND
+        }
+
+        if (centerPoint == null) {
+            centerPoint = PointF()
+        }
+        if (paintWidth < 1) {
+            paintWidth = 180f
+            centerPoint!!.x = (width / 2).toFloat()
+            centerPoint!!.y = (height / 2).toFloat()
+            initRectF()
+        }
+        Log.e("TEST", "onMeasure$paintWidth")
+        bottomCirclePaint!!.strokeWidth = paintWidth
+    }
+
+    private fun initRectF() {
+        if (InnerRectF == null) {
+            InnerRectF = RectF()
+        }
+        val radius = paintWidth * 3 / 2 + 6
+        InnerRectF!!.top = centerPoint!!.y - radius
+        InnerRectF!!.left = centerPoint!!.x - radius
+        InnerRectF!!.bottom = centerPoint!!.y + radius
+        InnerRectF!!.right = centerPoint!!.x + radius
+        val lg = LinearGradient(InnerRectF!!.left, InnerRectF!!.top, InnerRectF!!.right, InnerRectF!!.bottom, Color.parseColor(progressStartColor), Color.parseColor(progressEndColor), Shader.TileMode.MIRROR)
+        mProgressPaint!!.setShader(lg)
+    }
+
+    fun setCenterPoint(x: Float, y: Float) {
+        Log.e("TEST", "setCenterPoint$x   $y")
+        if (centerPoint == null) {
+            centerPoint = PointF()
+        }
+        centerPoint!!.x = x
+        centerPoint!!.y = y
+        initRectF()
+        postInvalidate()
+    }
+
+    fun setProgress(progress: Int) {
+        this.progress = progress
+        postInvalidate()
+    }
+
+    fun setPaintWidth(paintWidth: Float) {
+        Log.e("TEST", "setPaintWidth$paintWidth")
+        this.paintWidth = paintWidth
+    }
+
+}

+ 9 - 9
app/src/main/res/layout/dialog_validate_face.xml

@@ -17,15 +17,8 @@
         android:background="@color/qmui_s_transparent"  >
 
 
-        <!--显示焦点的框-->
-        <com.ethan.psbc.ui.widget.CameraFocusView
-            android:id="@+id/focus_view"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            android:visibility="gone"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintTop_toTopOf="parent" />
+
+
 
         <!--相机预览界面-->
         <androidx.camera.view.PreviewView
@@ -43,6 +36,13 @@
 
     </androidx.constraintlayout.widget.ConstraintLayout>
 
+
+
+<!--            <com.ethan.psbc.ui.widget.CircleProgressView-->
+<!--                android:id="@+id/circle"-->
+<!--                android:layout_width="match_parent"-->
+<!--                android:layout_height="match_parent" />-->
+
     <androidx.appcompat.widget.AppCompatButton
         android:id="@+id/take_photo"
         android:layout_width="@dimen/dp_375"