Ao adicionar uma visualização ao seu app, use a
PreviewView
, que é uma
View
que pode ser cortada, redimensionada e girada para que a exibição fique adequada.
A visualização da imagem é transmitida para uma superfície dentro da PreviewView
quando a
câmera é ativada.
Usar a PreviewView
A implementação de uma visualização para o CameraX usando PreviewView
envolve as seguintes etapas, abordadas nas próximas seções:
- Configurar um
CameraXConfig.Provider
(opcional). - Adicionar uma
PreviewView
ao seu layout. - Solicitar um
ProcessCameraProvider
. - Verificar se
ProcessCameraProvider
existe ao criarView
. - Selecionar uma câmera e vincular o ciclo de vida e casos de uso.
O uso de PreviewView
tem algumas limitações. Ao usar PreviewView
, não é possível realizar nenhuma das seguintes ações:
- Criar uma
SurfaceTexture
para configurar emTextureView
ePreview.SurfaceProvider
. - Recuperar a
SurfaceTexture
naTextureView
e configurá-la emPreview.SurfaceProvider
. - Conseguir a
Surface
daSurfaceView
e configurá-la emPreview.SurfaceProvider
.
Se qualquer um desses eventos acontecer, a Preview
vai interromper o streaming de frames para a
PreviewView
.
Adicionar uma PreviewView ao layout
O exemplo a seguir mostra uma PreviewView
em um layout:
<FrameLayout android:id="@+id/container"> <androidx.camera.view.PreviewView android:id="@+id/previewView" /> </FrameLayout>
Solicitar um CameraProvider
O código a seguir mostra como solicitar um CameraProvider
:
Kotlin
import androidx.camera.lifecycle.ProcessCameraProvider import com.google.common.util.concurrent.ListenableFuture class MainActivity : AppCompatActivity() { private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider> override fun onCreate(savedInstanceState: Bundle?) { cameraProviderFuture = ProcessCameraProvider.getInstance(this) } }
Java
import androidx.camera.lifecycle.ProcessCameraProvider import com.google.common.util.concurrent.ListenableFuture public class MainActivity extends AppCompatActivity { private ListenableFuture<ProcessCameraProvider> cameraProviderFuture; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { cameraProviderFuture = ProcessCameraProvider.getInstance(this); } }
Verificar a disponibilidade do CameraProvider
Depois de solicitar um CameraProvider
, verifique se a inicialização foi bem-sucedida quando a visualização for criada. O código a seguir mostra como fazer isso:
Kotlin
cameraProviderFuture.addListener(Runnable { val cameraProvider = cameraProviderFuture.get() bindPreview(cameraProvider) }, ContextCompat.getMainExecutor(this))
Java
cameraProviderFuture.addListener(() -> { try { ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); bindPreview(cameraProvider); } catch (ExecutionException | InterruptedException e) { // No errors need to be handled for this Future. // This should never be reached. } }, ContextCompat.getMainExecutor(this));
Para ver um exemplo da função bindPreview
usada nesta amostra, consulte o código
fornecido na próxima seção.
Selecionar uma câmera e vincular o ciclo de vida e os casos de uso
Após criar e confirmar o CameraProvider
, faça o seguinte:
- Crie uma
Preview
. - Especifique a opção
LensFacing
da câmera desejada. - Vincule a câmera selecionada e os casos de uso ao ciclo de vida.
- Conecte a
Preview
àPreviewView
.
O código a seguir mostra um exemplo:
Kotlin
fun bindPreview(cameraProvider : ProcessCameraProvider) { var preview : Preview = Preview.Builder() .build() var cameraSelector : CameraSelector = CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build() preview.setSurfaceProvider(previewView.getSurfaceProvider()) var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview) }
Java
void bindPreview(@NonNull ProcessCameraProvider cameraProvider) { Preview preview = new Preview.Builder() .build(); CameraSelector cameraSelector = new CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build(); preview.setSurfaceProvider(previewView.getSurfaceProvider()); Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview); }
Observe que bindToLifecycle()
retorna um objeto
Camera
. Para ter mais informações sobre como controlar a saída da câmera, como o zoom e a
exposição, consulte Saída da câmera.
Você concluiu a implementação da prévia da câmera. Crie seu app e confirme se a visualização aparece no app e funciona conforme o esperado.
Outros controles para a PreviewView
A PreviewView
do CameraX fornece outras APIs para configurar propriedades
como:
- O modo de implementação para renderizar streams de prévia.
- O tipo de escala da imagem de prévia.
Modo de implementação
A PreviewView
pode usar um dos seguintes modos para renderizar um stream de prévia na
View
de destino:
PERFORMANCE
é o modo padrão. APreviewView
usa umaSurfaceView
para mostrar o stream de vídeo, mas usaTextureView
em determinados casos. ASurfaceView
tem uma superfície de desenho dedicada, que tem mais chances de ser implementada com uma sobreposição de hardware do compositor de hardware interno, principalmente quando não há outros elementos da interface (como botões) sobre o vídeo de prévia. Ao renderizar com uma sobreposição de hardware, os frames do vídeo evitam um caminho de GPU, o que pode reduzir a latência e o consumo de energia da plataforma.Modo
COMPATIBLE
. Nesse modo, aPreviewView
usa umaTextureView
que, ao contrário daSurfaceView
, não tem uma superfície de desenho dedicada. Como resultado, o vídeo é renderizado com mesclagem para que possa ser mostrado. Durante essa etapa extra, o aplicativo pode executar outros processamentos, como fazer o dimensionamento e a rotação dos vídeos sem restrições.
Use PreviewView.setImplementationMode()
para selecionar o modo de implementação adequado para seu aplicativo. Caso o modo
PERFORMANCE
padrão não seja adequado para seu aplicativo, o exemplo de
código a seguir mostra como definir o modo COMPATIBLE
:
Kotlin
// viewFinder is a PreviewView instance viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE
Tipo de escala
Quando a resolução do vídeo de prévia é diferente das dimensões da sua PreviewView
de destino, o conteúdo do vídeo precisa ser ajustado à prévia, sendo cortado ou
usando o efeito letterbox, sem mudar a proporção original. A PreviewView
fornece os
seguintes ScaleTypes
para essa finalidade:
FIT_CENTER
,FIT_START
eFIT_END
para o efeito letterbox. O conteúdo completo do vídeo é dimensionado (para cima ou para baixo) no tamanho máximo que pode ser mostrado naPreviewView
de destino. No entanto, embora o frame completo do vídeo esteja visível, algumas partes da tela podem ficar em branco. Dependendo de qual dos três tipos de escala você escolher, o frame do vídeo será alinhado ao centro, início ou fim da prévia de destino.Use
FILL_CENTER
,FILL_START
eFILL_END
para cortar. Se um vídeo não corresponder à proporção daPreviewView
, apenas uma parte do conteúdo ficará visível, mas vai preencher toda aPreviewView
.
O tipo de escala padrão que o CameraX usa é FILL_CENTER
. Use PreviewView.setScaleType()
para definir o tipo de escala mais adequado para seu aplicativo. O exemplo
de código a seguir define o tipo de escala FIT_CENTER
.
Kotlin
// viewFinder is a PreviewView instance viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER
O processo para reproduzir um vídeo consiste nas seguintes etapas:
- Dimensione o vídeo:
- Para tipos de escala
FIT_*
, dimensione o vídeo commin(dst.width/src.width, dst.height/src.height)
. - Para tipos de escala
FILL_*
, dimensione o vídeo commax(dst.width/src.width, dst.height/src.height)
.
- Para tipos de escala
- Alinhe o vídeo dimensionado com a
PreviewView
de destino:- Para
FIT_CENTER/FILL_CENTER
, centralize o vídeo dimensionado e aPreviewView
de destino. - Para
FIT_START/FILL_START
, alinhe o vídeo dimensionado e aPreviewView
de destino ao canto superior esquerdo de cada um. - Para
FIT_END/FILL_END
, alinhe o vídeo dimensionado e aPreviewView
de destino em relação ao canto inferior direito de cada um.
- Para
Por exemplo, aqui temos um vídeo de origem de 640 x 480 e uma PreviewView
de destino de
1920 x 1080:
A imagem a seguir mostra o processo de dimensionamento
FIT_START
/ FIT_CENTER
/ FIT_END
:
O processo funciona assim:
- Ajuste o frame do vídeo (mantendo a proporção original) com
min(1920/640, 1080/480) = 2.25
para conseguir um frame de vídeo intermediário de 1440 x 1080. - Alinhe o frame do vídeo de 1440 x 1080 à
PreviewView
de 1920 x 1080.- Para
FIT_CENTER
, alinhe o frame do vídeo ao centro da janela dePreviewView
. As colunas inicial e final de 240 pixels daPreviewView
estão em branco. - Para
FIT_START
, alinhe o frame do vídeo ao início (canto superior esquerdo) da janela dePreviewView
. As colunas finais de 480 pixels daPreviewView
estão em branco. - Para
FIT_END
, alinhe o frame do vídeo ao final (canto inferior direito) da janelaPreviewView
. As colunas iniciais de 480 pixels daPreviewView
estão em branco.
- Para
A imagem a seguir mostra o processo de dimensionamento
FILL_START
/ FILL_CENTER
/ FILL_END
:
O processo funciona assim:
- Dimensione o frame do vídeo com
max(1920/640, 1080/480) = 3
para conseguir um frame intermediário de 1920 x 1440, que é maior que o tamanho da janela dePreviewView
. - Corte o frame do vídeo de 1920 x 1440 para que ele se ajuste à janela de
PreviewView
de 1920 x 1080.- Para
FILL_CENTER
, corte de 1920 x 1440 para 1920 x 1080 do centro do vídeo dimensionado. As 180 linhas de vídeo nas partes de cima e de baixo não ficam visíveis. - Para
FILL_START
, corte de 1920 x 1440 para 1920 x 1080 do início do vídeo dimensionado. As últimas 360 linhas de vídeo não ficam visíveis. - Para
FILL_END
, corte de 1920 x 1440 para 1920 x 1080 do fim do vídeo dimensionado. As primeiras 360 linhas de vídeo não ficam visíveis.
- Para
Outros recursos
Para saber mais sobre o CameraX, consulte os seguintes recursos.
Codelab
Exemplo de código