1. Introdução¶
A BCC Face é um biblioteca de Android feita para ser integrada em uma aplicação Android.
A biblioteca utiliza a câmera do dispositivo para tirar uma foto da face para propósitos biométricos. Ela provê um teste simples de vivacidade ativo, requerendo que a pessoa sorria por alguns segundos e/ou olhe para a direita ou esquerda. O teste de vivacidade inclui uma opção para falar as instruções, facilitando o fluxo para os usuários. Adicionalmente, ela provê um teste de vivacidade passivo que pode ser usado para verificar se a foto foi tirada de uma pessoa real sem requerer interação do usuário.
Esse manual está atualizado para a versão 4.6.1
do BCC Face Mobile Android.
Attention
O teste de vivacidade passivo está disponível somente a partir da versão 4.4.0
.
1.1. Requisitos¶
A BCC Face é uma biblioteca de Android e deve ser importada no projeto-alvo.
Versão mínima do Android: Android 6.0 (SDK 23), “Marshmallow”.
O aparelho móvel deve possuir uma câmera.
O aplicativo nativo deve ser compilado com tecnologia Android.
Ambiente de desenvolvimento: Uma IDE Android é necessária, como o Android Studio (recomendado).
Dependências externas adicionais:
- Google ML Kit, face-detection versão 16.0.2;
- Lottie, versão 3.0.0;
- Libyuv-android, versão 1.0.0;
Serviços externos:
- Firebase, pelo Google. Uma conta é necessária, mas nenhuma cobrança será aplicada, pois a biblioteca usa apenas APIs no dispositivo.
2. Instalação¶
2.1. Adicionando a biblioteca do projeto do App¶
A biblioteca BCC Face é fornecida pela Griaule como um arquivo .aar
.
Para adicionar a biblioteca, acesse o diretório do seu projeto, abra a pasta app e crie os diretórios libs/bccface
. Em seguida, acione a dependência bccfacelib-release.aar
. A estrutura de pastas deve ser semelhante a essa:
A próxima etapa é tornar esses arquivos visíveis para as dependências do gradle. Para fazer isso, adicione a seguinte linha no arquivo build.gradle (:app)
no objeto de dependências:
dependencies {
[...]
implementation fileTree(dir: 'libs/bccface', include: ['*.aar'])
}
Dentro do arquivo build.gradle (:app)
, adicione também as opções de compilação e defina a compatibilidade de origem e a compatibilidade de destino para usar 1.8 (Java 8):
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
2.2. Configurando o Google ML Kit¶
É recomendado seguir as instruções fornecidas na “Option 1: Use the Firebase console setup workflow” da documentação do Firebase para Android: Adicionar o Firebase ao projeto para Android.
Uma conta é necessária, mas nenhuma cobrança será aplicada, pois a biblioteca usa apenas APIs no dispositivo: Veja os detalhes de precificação do Firebase.
Se a Opção 1 foi escolhida, certifique-se de gerar o arquivo google-services.json
e colocá-lo no diretório android/app/
.
Modifique os seguintes arquivos:
android/build.gradle
buildscript { ... dependencies { ... classpath 'com.google.gms:google-services:4.3.3' } }
android/app/build.gradle
, adicione ao final do arquivo:... apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' apply plugin: 'com.google.gms.google-services' ... android { ... buildFeatures { viewBinding = true dataBinding = true } } ... dependencies { ... implementation 'com.google.firebase:firebase-analytics:17.2.2' // Add line above using analytics }
2.3. Configurando as dependências¶
Modifique os seguintes arquivos:
android/build.gradle
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
android/app/build.gradle
... dependencies { ... implementation project(path: ':bccfacelib') // ANDROIDX // implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android.material:material:1.1.0' // Google MLKIT // implementation 'com.google.mlkit:face-detection:16.0.2' // LOTTIE // implementation 'com.airbnb.android:lottie:3.0.0' // LIBYUV // implementation 'com.github.xiaoxiaoqingyi:libyuv-android:v1.0' // CAMERA X // def camerax_version = "1.2.0-rc01" // CameraX core library using camera2 implementation implementation "androidx.camera:camera-camera2:$camerax_version" // CameraX Lifecycle Library implementation "androidx.camera:camera-lifecycle:$camerax_version" // CameraX View class implementation "androidx.camera:camera-view:$camerax_version" }
3. Uso¶
3.1. Parâmetros e Construtor¶
Para usar a biblioteca BCC Face corretamente, certos parâmetros são necessários.
Um exemplo simples de uso de biblioteca é mostrado abaixo:
BCCFaceBuilder(this, this).initializeCapture()
O construtor da classe BCCFaceBuilder
recebe os seguintes parâmetros:
context:Context
- O contexto da aplicação.delegate:BCCFaceDelegate
- Interface responsável por notificar os eventos de captura, como falha ou sucesso.
A classe BCCFaceBuilder
é responsável por gerenciar as configurações de uso do BCCFace
. Os parâmetros a seguir são aceitos para configuração da captura biométrica e comportamento do software:
buildSmileCheck(smileProbability: Float = 0.8f)
- Adiciona o teste de vivacidade por meio de verificação de sorriso e define o limiar de aceitação. Essa funcionalidade é ativada por padrão.removeSmileCheck()
- Remove o teste de vivacidade por meio de sorriso.buildRotationCheck(livenessConfigList: List\<HeadRotationCheck>,
headRotationAngle: Float = 20f)
- Define uma lista de testes de vivacidade para rotação de face e o ângulo máximo de rotação. Essa funcionalidade é ativada por padrão. As opções para rotação de face são:enum class HeadRotationCheck { randomRotation, leftRotation, rightRotation; }
removeHeadRotation()
- Remove o teste de vivacidade por meio de rotação de face.addPassiveLiveness()
- Adiciona o teste de vivacidade passivo. Essa funcionalidade é usada para verificar se a foto capturada é de uma pessoa real sem requerer interação do usuário. Para usar essa funcionalidade, você DEVE desabilitar os testes de vivacidade ativos (removeSmileCheck()
eremoveHeadRotation()
) que são adicionados por padrão.buildSpeechSettings(speechSettings:SpeechSettings?)
- Define os critérios para a configuração de acessibilidade (leitura das instruções) usando os seguintes parâmetros:class SpeechSettings( val volume: Float = 1.0f, val startsMuted: Boolean = true, val pitch: Float = 1.0f, val speed: Float = 1.0f )
volume
- O volume do áudio entre0.0
e1.0
.startsMuted
- Define se as instruções iniciarão silenciadas ou não (true
para silenciar).pitch
- Define o timbre de voz para as instruções entre0.5
(grave) e2.0
(agudo).speed
- Define a velocidade de leitura das instruções. Este valor deve ser positivo.
Os valores predeterminados podem ser acessados por meio da seguinte variável estática:
class SpeechSettings { companion object { val defaultSpeechSettings = SpeechSettings() } }
removeSpeech()
- Remove a leitura de acessibilidade.setReviewEnable(enable: Boolean)
- Define se a tela de revisão da captura biométrica será habilitada ou não.setInstructionEnable(enable: Boolean)
- Define se a tela de instruções será habilitada ou não.forceLanguage(language:BCCFaceAPI.BCCLanguages?)
- Força as instruções a serem exibidas em um idioma específico. Se o idioma do dispositivo não for suportado, inglês será usado. Os idiomas suportados são:enum class BCCLanguages(val locale: Locale) { ptBR(Locale("pt", "br")), enUS(Locale.US), esMX(Locale("es", "mx")), deviceLanguage(Locale.getDefault()); }
removeLanguage()
- Remove o idioma forçado.enableFlipCameraButton(enable: Boolean)
- Ativa (true
) ou desativa (false
) a presença do botão de troca de câmera (frontal ou traseira). Padrão: ativado (true
).setCameraInitialDirection(CameraFacingDirection.<FRONT or BACK>)
- Define a direção inicial da câmera, escolher entre:CameraFacingDirection.FRONT
- Câmera frontal (definição padrão).CameraFacingDirection.BACK
- Câmera traseira.
Todas as configurações de direção da câmera são obtidas por meio da combinação dos métodos enableFlipCameraButton
e setCameraInitialDirection
. Por exemplo:
- Iniciar com a câmera frontal e habilitar o botão de troca de câmera:
BCCFaceBuilder(this, this) .enableFlipCameraButton(true) .setCameraInitialDirection(CameraFacingDirection.FRONT)
- Iniciar com a câmera traseira e desabilitar o botão de troca de câmera:
BCCFaceBuilder(this, this) .enableFlipCameraButton(false) .setCameraInitialDirection(CameraFacingDirection.BACK)
Para referência, a lista completa de parâmetros e valores padrão é:
var showPhotoReview: Boolean = false,
var showInstructionScreen: Boolean = false,
var stopVerifyEyesOpenTimeout: Long = 20,
var useICAO: Boolean = false,
var smilingProbabilityThreshold: Float = 0.8f,
var rotateAngle: Float = 20f,
var livenessList: MutableList<LivenessTypes> = mutableListOf(LivenessTypes.SMILE, LivenessTypes.ROTATION_RANDOM),
var language: BCCFaceAPI.BCCLanguages? = null,
var speechSettings: SpeechSettings? = SpeechSettings(),
var activityResults: FaceCaptureActivityResults? = null
Attention
O teste de vivacidade ativo (usando sorriso e rotação aleatória de cabeça) é habilitado por padrão. Para usar apenas o teste de vivacidade passivo, antes de adicioná-lo, é necessário remover os métodos de vivacidade ativa do construtor:
BCCFaceBuilder(this, this)
.removeSmileCheck()
.removeHeadRotation()
.addPassiveLiveness()
Aqui está um trecho de código para iniciar uma captura usando apenas o teste de vivacidade passivo:
// Da Activity desejada...
// Crie o builder
BCCFaceBuilder faceBuilder = new BCCFaceBuilder(this, this);
// Configure o builder
faceBuilder
.removeSmileCheck()
.removeHeadRotation()
.addPassiveLiveness();
// Inicie a captura a partir do builder
faceBuilder.initializeCapture();
3.2. Valores de Retorno¶
Os resultados da última captura facial podem ser recuperados através do método faceCaptureDidFinish
da interface BCCFaceDelegate
:
fun faceCaptureDidFinish(
data: BCCFaceReturnData,
analytics: BCCFaceReturnAnalytics
)
O objeto data
contém ambas as imagens capturadas durante o processo:
class BCCFaceReturnData {
val originalPhoto: Bitmap?
val croppedPhoto: Bitmap?
// Resultado do teste de vivacidade passivo
val passiveResult: ByteArray?
}
As propriedades retornadas são:
originalPhoto
(image) - Foto original tirada pela câmera.croppedPhoto
(image) - Foto cortada, que é a imagem da face recortada da foto original.passiveResult
(ByteArray) - Conteúdo do arquivo de coleta para teste de vivacidade passivo. Está presente apenas se capturado com sucesso. É o retorno da coleta para teste de vivacidade passivo como JPEG ByteArray. Esses dados podem ser salvos/exportados diretamente para um arquivo ou enviados para a rede (para rede: a codificação do sistema pode ser facilmente feita, por exemplo, uma string Base64).
Note
As propriedades originalPhoto
e croppedPhoto
retornam nulo (null) quando a captura é realizada apenas para testes passivos (ou seja, sem incluir um teste ativo).
Caso o usuário encerre a aplicação antes de finalizar a captura biométrica, o método faceCaptureDidAbort
será chamado. Você pode implementar este método para tratar este cenário.
3.3. Projeto Exemplo¶
Este é um exemplo de projeto funcional para captura de face utilizando o BCC Mobile Face Android:
package com.example.bccfaceexample
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.bccfaceexample.databinding.ActivityMainBinding
import com.griaule.bccfacelib.analytics.BCCFaceReturnAnalytics
import com.griaule.bccfacelib.faceApi.BCCFaceBuilder
import com.griaule.bccfacelib.faceApi.BCCFaceDelegate
import com.griaule.bccfacelib.faceApi.BCCFaceReturnData
class MainActivity : AppCompatActivity(), BCCFaceDelegate {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setupListeners()
}
private fun setupListeners() {
binding.startCaptureButton.setOnClickListener { initializeCapture() }
}
private fun initializeCapture() {
BCCFaceBuilder(this, this)
.setInstructionEnable(true)
.setReviewEnable(true)
.initializeCapture()
}
override fun faceCaptureDidAbort(
analytics: BCCFaceReturnAnalytics
) {
// ...
}
override fun faceCaptureDidFinish(
data: BCCFaceReturnData,
analytics: BCCFaceReturnAnalytics
) {
// ...
}
}