Browse Source

:seedling: 整合人脸SDK

everywindchase 10 months ago
parent
commit
90c448a880

+ 109 - 8
app/src/main/java/com/ethan/psbc/ui/dialogs/DialogValidateFace.kt

@@ -4,6 +4,7 @@ import android.Manifest
 import android.content.Context
 import android.content.pm.PackageManager
 import android.graphics.ImageFormat
+import android.os.Environment
 import android.util.Log
 import android.util.Size
 import android.view.View
@@ -18,19 +19,26 @@ import androidx.camera.view.PreviewView
 import androidx.core.app.ActivityCompat
 import androidx.core.content.ContextCompat
 import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
 import cn.face.sdk.FaceDetTrack
 import cn.face.sdk.FaceInfo
 import cn.face.sdk.FaceInterface
 import cn.face.sdk.FaceRecog
 import com.ethan.psbc.R
+import com.ethan.psbc.commons.IViewOnNoDoubleClickListener
 import com.ethan.psbc.databinding.DialogValidateFaceBinding
 import com.ethan.psbc.managers.impls.ImplFaceManager
 import com.lxj.xpopup.impl.FullScreenPopupView
-import org.koin.core.component.KoinComponent
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 import org.koin.core.component.inject
+import java.io.File
 import java.nio.ByteBuffer
+import java.util.*
+import java.util.concurrent.Executor
 import java.util.concurrent.ExecutorService
 import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
 import kotlin.math.min
 
 
@@ -38,7 +46,7 @@ import kotlin.math.min
  * <p>人脸验证界面</p>
  * @author gy
  */
-class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), KoinComponent {
+class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), IViewOnNoDoubleClickListener {
 
 
 
@@ -66,12 +74,34 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), Ko
         val faceHandleRet:Int=mFace.initSdk()
         this.faceHandleRet=faceHandleRet
         runCamera(this, mBinding.mPreviewView, faceHandleRet, context = context)
-        mBinding.cameraLayout.visibility= View.VISIBLE
         mBinding.mPreviewView.bringToFront()
+        mBinding.takePhoto.setOnClickListener(this)
     }
 
 
+    override fun onClickNoDouble(view: View) {
+        lifecycleScope.launch(context = Dispatchers.Main) {
+            when (view) {
+                mBinding.takePhoto -> oneShot(view)
+            }
+        }
+
+    }
 
+    fun oneShot(view:View){
+        val dirPath= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).absolutePath;
+        val outputFileOptions = ImageCapture.OutputFileOptions.Builder(File(dirPath,"demo_"+Date().time+".jpg")).build()
+        imageCamera?.takePicture(outputFileOptions, cameraExecutor,
+            object : ImageCapture.OnImageSavedCallback {
+                override fun onError(error: ImageCaptureException)
+                {
+                    // insert your code here.
+                }
+                override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
+                    // insert your code here.
+                }
+            })
+    }
 
 
 
@@ -102,11 +132,15 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), Ko
 
                 cameraExecutor = Executors.newSingleThreadExecutor()
                 val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
+
+
+
             cameraProviderFuture.addListener({
                 cameraProvider = cameraProviderFuture.get()//获取相机信息
 
 
 
+
                 val resolutionBuilder = ResolutionSelector
                     .Builder()
                     .setResolutionStrategy(ResolutionStrategy(Size(640, 480), ResolutionStrategy.FALLBACK_RULE_NONE))
@@ -119,7 +153,6 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), Ko
 
 
 
-
                 imageCamera = ImageCapture.Builder()
                     .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                     .build()
@@ -257,17 +290,31 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), Ko
 
                 }
 
-                val cameraCtrl=camera.cameraControl
-                val cameraInfo=camera.cameraInfo
+
+                preview?.setSurfaceProvider(previewView?.surfaceProvider)
 
 
 
+        }, ContextCompat.getMainExecutor(context))
 
-                preview?.setSurfaceProvider(previewView?.surfaceProvider)
 
+        camera.cameraInfo.cameraState.observe(lifecycleOwner) { value ->
+            when (value.type) {
+                CameraState.Type.OPEN         ->{
+                    Log.d("demo", "相机正在打开中" )
+                    if (null != previewView) {
+                        autoFocus(camera, previewView, 200f, 200f, true, ContextCompat.getMainExecutor(context))
+                    }
+                }
 
+                CameraState.Type.PENDING_OPEN -> Log.d("demo", "相机待打开" )
+                CameraState.Type.OPENING      -> Log.d("demo", "相机已打开" )
+                CameraState.Type.CLOSING      ->Log.d("demo", "相机关闭中" )
+                CameraState.Type.CLOSED       -> Log.d("demo", "相机已关闭" )
+            }
+
+        }
 
-        }, ContextCompat.getMainExecutor(context))
     }
 
 
@@ -282,4 +329,58 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), Ko
 
 
 
+
+    fun autoFocus(camera:Camera,previewView:PreviewView,x:Float,y:Float,auto:Boolean,executor: Executor) {
+
+
+
+
+       val cameraInfo= camera.cameraInfo
+        val cameraCrtl= camera.cameraControl
+
+
+
+        cameraCrtl.cancelFocusAndMetering()
+
+        val createPoint:MeteringPoint=if(auto){
+            val meteringPointFactory=DisplayOrientedMeteringPointFactory(
+                previewView.display,
+                cameraInfo,
+                previewView.width.toFloat(),
+                previewView.height.toFloat()
+            )
+
+            meteringPointFactory.createPoint(x,y)
+
+        }else{
+           val meteringPointFactory= previewView.meteringPointFactory;
+            meteringPointFactory.createPoint(x,y)
+        }
+
+      val build= FocusMeteringAction.Builder(createPoint)
+            .setAutoCancelDuration(3,TimeUnit.SECONDS).build()
+
+       var result=cameraCrtl.startFocusAndMetering(build)
+
+        result.addListener({
+            try{
+                if(result.get().isFocusSuccessful) {
+                    Log.d("demo", "聚集成功")
+
+                }else{
+                    Log.d("demo", "聚集失败")
+                }
+
+            }catch (e:Exception){
+                Log.d("demo","聚集异常${e.message}")
+            }
+
+
+
+        },executor)
+
+    }
+
+
+
 }

+ 17 - 4
app/src/main/res/layout/dialog_validate_face.xml

@@ -10,11 +10,11 @@
 
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/camera_layout"
-        android:layout_width="280dp"
-        android:layout_height="350dp"
+        android:layout_width="640dp"
+        android:layout_height="480dp"
         android:gravity="center"
         android:layout_gravity="center"
-        android:background="@color/qmui_s_transparent"  android:visibility="gone">
+        android:background="@color/qmui_s_transparent"  >
 
 
 
@@ -30,7 +30,20 @@
 
     </androidx.constraintlayout.widget.ConstraintLayout>
 
-
+    <androidx.appcompat.widget.AppCompatButton
+        android:id="@+id/take_photo"
+        android:layout_width="@dimen/dp_375"
+        android:layout_height="@dimen/dp_60"
+        android:layout_marginStart="@dimen/dp_12.5"
+        android:layout_marginTop="@dimen/dp_82.5"
+        android:layout_marginEnd="@dimen/dp_12.5"
+        android:gravity="center"
+        android:text="拍照"
+        android:textColor="@color/qmui_config_color_white"
+        android:textSize="@dimen/sp_20"
+        android:textStyle="bold"
+        app:bl_corners_radius="@dimen/dp_30"
+        app:bl_solid_color="@color/color_12C194"/>