Tirando fotos
Capture e salve uma imagem.
Tirando fotos é uma aula grátis de Android Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Android Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Android Academy inclui 4 aulas no total.
Capturando uma foto
Com uma visualização na tela, o próximo passo é tirar uma foto. A CameRX cuida disso com o caso de uso ImageCapture.
Você associará ImageCapture junto com a visualização, chamará takePicture() quando o usuário tocar no botão do obturador e salvará o resultado na galeria do dispositivo.
Criando o caso de uso ImageCapture
ImageCapture é configurado com um builder. Uma opção útil é o modo de captura, que estabelece um equilíbrio entre latência e qualidade:
CAPTURE_MODE_MINIMIZE_LATENCY— obturador rápido.CAPTURE_MODE_MAXIMIZE_QUALITY— melhor imagem, um pouco mais lento.
val imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build()Associando Preview e ImageCapture
Você pode associar vários casos de uso ao mesmo tempo. Passe preview e imageCapture para bindToLifecycle para que a câmera forneça a transmissão ao vivo e esteja pronta para tirar uma foto.
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
lifecycleOwner,
CameraSelector.DEFAULT_BACK_CAMERA,
preview,
imageCapture
)Onde salvar: MediaStore
A maneira moderna e compatível com o armazenamento com escopo para salvar uma foto é usar o MediaStore. Você descreve o arquivo (nome, tipo MIME e pasta) com ContentValues e deixa o sistema colocá-lo na coleção compartilhada Pictures.
Isso funciona sem a permissão antiga WRITE_EXTERNAL_STORAGE no Android 10 ou superior.
val name = "photo_${System.currentTimeMillis()}"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/MyApp")
}Opções de saída
Para informar à CameraX onde gravar o JPEG, crie um OutputFileOptions a partir do resolvedor de conteúdo, do URI da coleção de destino e dos seus ContentValues.
val outputOptions = ImageCapture.OutputFileOptions
.Builder(
context.contentResolver,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues
)
.build()Chamando takePicture()
Agora inicie a captura. takePicture() recebe as opções de saída, um Executor e um callback. A CameRX informa o sucesso ou o erro de forma assíncrona.
Use ContextCompat.getMainExecutor(context) para que o callback seja executado na thread principal.
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(context),
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val savedUri = output.savedUri
// Photo saved! Show a confirmation.
}
override fun onError(exc: ImageCaptureException) {
// Handle the failure.
}
}
)Como lidar com o resultado
Em caso de sucesso, OutputFileResults.savedUri fornece o URI da imagem salva. Você pode exibi-la (com Coil), compartilhá-la ou mostrar uma Snackbar confirmando o salvamento.
Em caso de erro, ImageCaptureException informa o que deu errado — registre o erro e informe o usuário.
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val uri = output.savedUri ?: return
Toast.makeText(context, "Saved: $uri", Toast.LENGTH_SHORT).show()
}Conectando um botão do obturador
No Compose, sobreponha um botão do obturador à visualização usando uma Box. Eleve a referência de ImageCapture para que o onClick do botão possa chamar takePhoto.
Box(modifier = Modifier.fillMaxSize()) {
CameraPreview(imageCapture = imageCapture)
IconButton(
onClick = { takePhoto(context, imageCapture) },
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(32.dp)
) {
Icon(Icons.Default.PhotoCamera, contentDescription = "Take photo")
}
}Extraindo takePhoto()
Mantenha seu componente composable organizado, transferindo a lógica de captura para uma função auxiliar. Ela recebe o contexto e o caso de uso ImageCapture, cria as opções de saída e chama takePicture.
fun takePhoto(context: Context, imageCapture: ImageCapture) {
val values = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "IMG_${System.currentTimeMillis()}")
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
}
val options = ImageCapture.OutputFileOptions.Builder(
context.contentResolver,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values
).build()
imageCapture.takePicture(
options,
ContextCompat.getMainExecutor(context),
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(o: ImageCapture.OutputFileResults) {}
override fun onError(e: ImageCaptureException) {}
}
)
}Flash e rotação
Dois toques finais:
- Flash: defina
imageCapture.flashModecomoFLASH_MODE_ON,OFFouAUTO. - Rotação: CameRX usa a rotação de destino para orientar corretamente o JPEG salvo; mantenha esse valor atualizado para garantir a orientação correta.
imageCapture.flashMode = ImageCapture.FLASH_MODE_AUTO
// Update target rotation when the device rotates:
imageCapture.targetRotation = display.rotationJuntando tudo
O fluxo completo de captura de fotos é: criar ImageCapture → vinculá-lo à visualização → ao tocar no obturador, criar OutputFileOptions e chamar takePicture → lidar com onImageSaved / onError.
Assim, você tem uma câmera completa que salva na galeria usando apenas algumas linhas.
Verificação rápida
Confirme que você entende o fluxo de captura de fotos.
Recapitulação
Agora você pode tirar e salvar fotos com CameRX:
- Crie um caso de uso
ImageCapturee vincule-o à visualização. - Descreva a saída com
ContentValueseMediaStorepara usar o armazenamento com escopo. - Chame
takePicture()comOutputFileOptions, um executor e umOnImageSavedCallback. - Leia
savedUriem caso de sucesso; lide comImageCaptureExceptionem caso de erro.
Em seguida, você gravará vídeos com o caso de uso VideoCapture.
Perguntas Frequentes
A aula “Tirando fotos” é grátis?
Sim — o texto completo de “Tirando fotos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Android Academy, atualize para CoddyKit PRO. O curso de Android Academy inclui 4 aulas no total.
O que vou aprender em “Tirando fotos”?
Capture e salve uma imagem. Você pratica Android Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Android Academy?
Nenhuma experiência prévia é necessária. Android Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Tirando fotos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Android Academy?
Sim. Cada aula de Android Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.