|
|
@@ -0,0 +1,197 @@
|
|
|
+package com.grkj.iscs.util
|
|
|
+
|
|
|
+import android.Manifest
|
|
|
+import android.content.Context
|
|
|
+import android.graphics.Bitmap
|
|
|
+import android.graphics.Point
|
|
|
+import android.hardware.Camera
|
|
|
+import android.util.DisplayMetrics
|
|
|
+import android.view.View
|
|
|
+import android.view.WindowManager
|
|
|
+import com.arcsoft.face.ActiveFileInfo
|
|
|
+import com.arcsoft.face.AgeInfo
|
|
|
+import com.arcsoft.face.ErrorInfo
|
|
|
+import com.arcsoft.face.Face3DAngle
|
|
|
+import com.arcsoft.face.FaceEngine
|
|
|
+import com.arcsoft.face.FaceInfo
|
|
|
+import com.arcsoft.face.GenderInfo
|
|
|
+import com.arcsoft.face.LivenessInfo
|
|
|
+import com.arcsoft.face.enums.DetectFaceOrientPriority
|
|
|
+import com.arcsoft.face.enums.DetectMode
|
|
|
+import com.grkj.iscs.R
|
|
|
+import com.grkj.iscs.model.Constants
|
|
|
+import com.grkj.iscs.util.log.LogUtil
|
|
|
+import com.grkj.iscs.view.activity.test.face.arcsoft.CameraHelper
|
|
|
+import com.grkj.iscs.view.activity.test.face.arcsoft.CameraListener
|
|
|
+import com.grkj.iscs.view.activity.test.face.arcsoft.NV21ToBitmap
|
|
|
+
|
|
|
+object ArcSoftUtil {
|
|
|
+ private var cameraHelper: CameraHelper? = null
|
|
|
+ private var previewSize: Camera.Size? = null
|
|
|
+ private val rgbCameraId = Camera.CameraInfo.CAMERA_FACING_BACK
|
|
|
+ private var faceEngine: FaceEngine? = null
|
|
|
+ private var afCode = -1
|
|
|
+ private val processMask: Int =
|
|
|
+ FaceEngine.ASF_AGE or FaceEngine.ASF_FACE3DANGLE or FaceEngine.ASF_GENDER or FaceEngine.ASF_LIVENESS
|
|
|
+
|
|
|
+ private const val ACTION_REQUEST_PERMISSIONS: Int = 0x001
|
|
|
+ var isActivated = false
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 所需的所有权限信息
|
|
|
+ */
|
|
|
+ private val NEEDED_PERMISSIONS: Array<String?> = arrayOf(
|
|
|
+ Manifest.permission.CAMERA,
|
|
|
+ Manifest.permission.READ_PHONE_STATE
|
|
|
+ )
|
|
|
+
|
|
|
+ fun checkActiveStatus(context: Context) {
|
|
|
+ val activeCode = FaceEngine.activeOnline(context, Constants.APP_ID, Constants.SDK_KEY)
|
|
|
+ when (activeCode) {
|
|
|
+ ErrorInfo.MOK -> {
|
|
|
+ isActivated = true
|
|
|
+ LogUtil.i("initEngine : active success")
|
|
|
+ }
|
|
|
+
|
|
|
+ ErrorInfo.MERR_ASF_ALREADY_ACTIVATED -> {
|
|
|
+ isActivated = true
|
|
|
+ LogUtil.i("initEngine : already activated")
|
|
|
+ }
|
|
|
+
|
|
|
+ else -> {
|
|
|
+ isActivated = false
|
|
|
+ LogUtil.e("initEngine : active failed $activeCode")
|
|
|
+ ToastUtils.tip(R.string.face_active_fail)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ val activeFileInfo = ActiveFileInfo()
|
|
|
+ val res = FaceEngine.getActiveFileInfo(context, activeFileInfo)
|
|
|
+ if (res == ErrorInfo.MOK) {
|
|
|
+ LogUtil.e("initEngine: getActiveFileInfo: $activeFileInfo")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fun initEngine(context: Context) {
|
|
|
+ faceEngine = FaceEngine()
|
|
|
+ afCode = faceEngine!!.init(
|
|
|
+ context,
|
|
|
+ DetectMode.ASF_DETECT_MODE_VIDEO,
|
|
|
+ DetectFaceOrientPriority.valueOf("ASF_OP_0_ONLY"),
|
|
|
+ 16,
|
|
|
+ 20,
|
|
|
+ FaceEngine.ASF_FACE_DETECT or FaceEngine.ASF_AGE or FaceEngine.ASF_FACE3DANGLE or FaceEngine.ASF_GENDER or FaceEngine.ASF_LIVENESS
|
|
|
+ )
|
|
|
+ LogUtil.i("initEngine: init: $afCode")
|
|
|
+ if (afCode != ErrorInfo.MOK) {
|
|
|
+ ToastUtils.tip(R.string.face_active_fail)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fun unInitEngine() {
|
|
|
+ if (afCode == 0) {
|
|
|
+ afCode = faceEngine!!.unInit()
|
|
|
+ LogUtil.i("unInitEngine: $afCode")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fun initCamera(context: Context, windowManager: WindowManager, preview: View, callBack: (Bitmap?) -> Unit) {
|
|
|
+ val metrics = DisplayMetrics()
|
|
|
+ windowManager.defaultDisplay.getMetrics(metrics)
|
|
|
+
|
|
|
+ val cameraListener: CameraListener = object : CameraListener {
|
|
|
+ override fun onCameraOpened(
|
|
|
+ camera: Camera,
|
|
|
+ cameraId: Int,
|
|
|
+ displayOrientation: Int,
|
|
|
+ isMirror: Boolean
|
|
|
+ ) {
|
|
|
+ LogUtil.i("onCameraOpened: $cameraId $displayOrientation $isMirror")
|
|
|
+ previewSize = camera.parameters.previewSize
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ override fun onPreview(nv21: ByteArray?, camera: Camera?) {
|
|
|
+ val faceInfoList: List<FaceInfo> = ArrayList()
|
|
|
+ var code = faceEngine!!.detectFaces(
|
|
|
+ nv21,
|
|
|
+ previewSize!!.width,
|
|
|
+ previewSize!!.height,
|
|
|
+ FaceEngine.CP_PAF_NV21,
|
|
|
+ faceInfoList
|
|
|
+ )
|
|
|
+ if (code == ErrorInfo.MOK && faceInfoList.size > 0) {
|
|
|
+ code = faceEngine!!.process(
|
|
|
+ nv21,
|
|
|
+ previewSize!!.width,
|
|
|
+ previewSize!!.height,
|
|
|
+ FaceEngine.CP_PAF_NV21,
|
|
|
+ faceInfoList,
|
|
|
+ processMask
|
|
|
+ )
|
|
|
+ if (code != ErrorInfo.MOK) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ val ageInfoList: List<AgeInfo> = ArrayList()
|
|
|
+ val genderInfoList: List<GenderInfo> = ArrayList()
|
|
|
+ val face3DAngleList: List<Face3DAngle> = ArrayList()
|
|
|
+ val faceLivenessInfoList: List<LivenessInfo> = ArrayList()
|
|
|
+ val ageCode = faceEngine!!.getAge(ageInfoList)
|
|
|
+ val genderCode = faceEngine!!.getGender(genderInfoList)
|
|
|
+ val face3DAngleCode = faceEngine!!.getFace3DAngle(face3DAngleList)
|
|
|
+ val livenessCode = faceEngine!!.getLiveness(faceLivenessInfoList)
|
|
|
+
|
|
|
+ // 有其中一个的错误码不为ErrorInfo.MOK,return
|
|
|
+ if ((ageCode or genderCode or face3DAngleCode or livenessCode) != ErrorInfo.MOK) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 自己加的,必须有活体检测
|
|
|
+ if (faceLivenessInfoList.none { it.liveness == LivenessInfo.ALIVE }) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ val bitmap = NV21ToBitmap(context).nv21ToBitmap(nv21, previewSize!!.width, previewSize!!.height)
|
|
|
+ LogUtil.i("识别结果 : ${bitmap == null} - $faceInfoList")
|
|
|
+ callBack(bitmap)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onCameraClosed() {
|
|
|
+ LogUtil.i("onCameraClosed: ")
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onCameraError(e: Exception) {
|
|
|
+ LogUtil.i("onCameraError: " + e.message)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onCameraConfigurationChanged(cameraID: Int, displayOrientation: Int) {
|
|
|
+ LogUtil.i("onCameraConfigurationChanged: $cameraID $displayOrientation")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ cameraHelper = CameraHelper.Builder()
|
|
|
+ .previewViewSize(Point(preview.measuredWidth, preview.measuredHeight))
|
|
|
+ .rotation(windowManager.defaultDisplay.rotation)
|
|
|
+ .specificCameraId(rgbCameraId ?: Camera.CameraInfo.CAMERA_FACING_FRONT)
|
|
|
+ .isMirror(false)
|
|
|
+ .previewOn(preview)
|
|
|
+ .cameraListener(cameraListener)
|
|
|
+ .build()
|
|
|
+ cameraHelper!!.init()
|
|
|
+ cameraHelper!!.start()
|
|
|
+ }
|
|
|
+
|
|
|
+ fun start(context: Context, windowManager: WindowManager, preview: View, callBack: (Bitmap?) -> Unit) {
|
|
|
+ initEngine(context)
|
|
|
+ initCamera(context, windowManager, preview, callBack)
|
|
|
+ }
|
|
|
+
|
|
|
+ fun stop() {
|
|
|
+ if (cameraHelper != null) {
|
|
|
+ cameraHelper!!.release()
|
|
|
+ cameraHelper = null
|
|
|
+ }
|
|
|
+ unInitEngine()
|
|
|
+ }
|
|
|
+}
|