Android中使用Azure Face API活体验证时如何获取验证照片
Android端Azure Face API活体检测获取验证照片方案
直接截取SurfaceView返回空白,是因为Azure Face SDK的预览流直接渲染到SurfaceView底层Surface,PixelCopy难以正确捕获;或是截取时机不对、尺寸配置有误。以下是三种可行解决方案:
方案一:利用SDK回调直接获取分析帧
这是最可靠的方式,FaceAnalyzer的回调能直接拿到验证环节的原始帧数据:
修改回调监听逻辑
在createFaceAnalyzer方法中,完善analyzing或analyzed事件监听:
private val analyzingListener = EventListener<FaceAnalyzingEventArgs> { args -> // 获取当前正在分析的帧Bitmap args.frame.bitmap?.let { frameBitmap -> // 后台线程处理Bitmap,避免主线程阻塞 CoroutineScope(Dispatchers.IO).launch { val base64Str = bitmapToBase64(frameBitmap) // 执行保存或上传操作 } } } private val analyzedListener = EventListener<FaceAnalyzedEventArgs> { args -> // 活体验证完成后,获取验证用的关键帧 args.result?.frame?.bitmap?.let { validBitmap -> val base64Str = bitmapToBase64(validBitmap) // 处理验证通过后的照片 } }
注意:
analyzed回调对应验证完成的节点,更适合获取最终验证照片;所有Bitmap处理操作需放到后台线程,避免ANR。
方案二:修复SurfaceView的PixelCopy截取问题
若坚持用SurfaceView,需解决渲染时机和尺寸匹配问题:
- 等待Surface渲染完成后再截取
mSurfaceView.holder.addCallback(object : SurfaceHolder.Callback { override fun surfaceCreated(holder: SurfaceHolder) { // 延迟500ms确保预览流已渲染完成 Handler(Looper.getMainLooper()).postDelayed({ usePixelCopy(mSurfaceView) { base64 -> // 处理截取结果 } }, 500) } override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {} override fun surfaceDestroyed(holder: SurfaceHolder) {} })
- 修正Bitmap尺寸配置
private fun usePixelCopy(view: SurfaceView, callback: (String) -> Unit) { val previewSize = mVisionSource?.cameraPreviewFormat val width = previewSize?.width ?: view.width val height = previewSize?.height ?: view.height val bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) PixelCopy.request(view, bmp, { result -> if (result == PixelCopy.SUCCESS) { callback(bitmapToBase64(bmp)) } }, Handler(Looper.getMainLooper())) }
方案三:替换SurfaceView为TextureView
TextureView支持直接获取当前帧,无需PixelCopy,捕获逻辑更简单:
- 布局替换为TextureView
<TextureView android:id="@+id/mTextureView" android:layout_width="match_parent" android:layout_height="match_parent"/>
- 修改VisionSource配置
val visionSourceOptions = VisionSourceOptions(this, this as LifecycleOwner) visionSourceOptions.setPreview(mTextureView) // 替换为TextureView mVisionSource = VisionSource.fromDefaultCamera(visionSourceOptions)
- 直接捕获帧
private fun captureValidFrame(): Bitmap? { return try { mTextureView.bitmap } catch (e: Exception) { null } }
在验证完成时调用该方法即可获取照片。
内容的提问来源于stack exchange,提问作者Woton Sampaio
相关产品推荐
相关产品推荐

