|
@@ -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)
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|