Partilhar via


Exibir a pré-visualização da câmara

Este artigo descreve como exibir rapidamente o fluxo de visualização da câmera em uma página XAML em um aplicativo da Plataforma Universal do Windows (UWP). Criar um aplicativo que capture fotos e vídeos usando a câmera exige que você execute tarefas como manipular a orientação do dispositivo e da câmera ou definir opções de codificação para o arquivo capturado. Para alguns cenários de aplicativos, você pode querer simplesmente mostrar o fluxo de visualização da câmera sem se preocupar com essas outras considerações. Este artigo mostra como fazer isso com um mínimo de código. Observe que você sempre deve desligar o fluxo de visualização corretamente quando terminar de usá-lo, seguindo as etapas abaixo.

Para obter informações sobre como escrever um aplicativo de câmera que captura fotos ou vídeos, consulte Captura básica de fotos, vídeos e áudio com MediaCapture.

Adicionar declarações de capacidade ao manifesto do aplicativo

Para que a sua aplicação acesse a câmera de um dispositivo, deve declarar que usa as capacidades do dispositivo: webcam e microfone .

Adicionar funcionalidades ao manifesto da aplicação

  1. No Microsoft Visual Studio, no Explorador de Soluções, abra o designer do manifesto da aplicação clicando duas vezes no item package.appxmanifest.
  2. Selecione a guia Recursos .
  3. Marque a caixa de seleção para Webcam e a caixa de seleção para Microfone .

Adicionar um CaptureElement à sua página

Use um CaptureElement para exibir o fluxo de visualização em sua página XAML.

<CaptureElement Name="PreviewControl" Stretch="Uniform"/>

Use o MediaCapture para iniciar o fluxo de visualização

O objeto MediaCapture é a interface do seu aplicativo para a câmera do dispositivo. Essa classe é um membro do namespace Windows.Media.Capture. O exemplo neste artigo também usa APIs dos namespaces Windows.ApplicationModel e System.Threading.Tasks , além daquelas incluídas pelo modelo de projeto padrão.

Adicione diretivas de uso para incluir os namespaces a seguir no arquivo de .cs da sua página.

//MainPage.xaml.cs
using Windows.UI.Core;
using Windows.UI.Xaml.Navigation;
using Windows.Media.Capture;
using Windows.ApplicationModel;
using System.Threading.Tasks;
using Windows.System.Display;
using Windows.Graphics.Display;

Declare uma variável de membro de classe para o objeto MediaCapture e uma variável booleana para indicar se a câmara está a mostrar a pré-visualização no momento.

MediaCapture mediaCapture;
bool isPreviewing;

Declare uma variável do tipo DisplayRequest que será usada para garantir que o ecrã não desligue enquanto a visualização estiver em execução.

DisplayRequest displayRequest = new DisplayRequest();

Crie um método auxiliar para iniciar a visualização da câmera, chamado StartPreviewAsync neste exemplo. Dependendo do cenário da sua aplicação, convém chamar esta função no manipulador de eventos OnNavigatedTo, que é chamado quando a página for carregada, ou aguardar e iniciar a pré-visualização em resposta a eventos da interface do utilizador.

Crie uma nova instância da classe MediaCapture e chame InitializeAsync para inicializar o dispositivo de captura. Este método pode falhar, em dispositivos que não têm uma câmara, por exemplo, por isso, deve-se chamá-lo de dentro de um bloco try. Uma UnauthorizedAccessException será gerada ao tentar inicializar a câmera caso o utilizador tenha desabilitado o acesso à câmera nas definições de privacidade do dispositivo. Você também verá essa exceção durante o desenvolvimento se tiver negligenciado a adição dos recursos adequados ao manifesto do aplicativo.

Importante Em algumas famílias de dispositivos, um prompt de consentimento do usuário é exibido para o usuário antes que seu aplicativo tenha acesso à câmera do dispositivo. Por esse motivo, você só deve chamar MediaCapture.InitializeAsync do thread principal da interface do usuário. Tentar inicializar a câmera de outro thread pode resultar em falha de inicialização.

Observação

O Windows permite que os usuários concedam ou neguem acesso à câmera do dispositivo no aplicativo Configurações do Windows, em Privacidade e Segurança -> Câmera. Ao inicializar o dispositivo de captura, os aplicativos devem verificar se têm acesso à câmera e lidar com o caso em que o acesso é negado pelo usuário. Para obter mais informações, consulte Manipular a configuração de privacidade da câmera do Windows.

Conecte o MediaCapture ao CaptureElement definindo a propriedade Source. Inicie a visualização chamando StartPreviewAsync. Esse método lançará um FileLoadException se outro aplicativo tiver controle exclusivo do dispositivo de captura. Consulte a próxima seção para saber como monitorizar alterações no controle exclusivo.

Ligue RequestActive para se certificar de que o dispositivo não entra em modo de suspensão enquanto a pré-visualização está em execução. Por fim, defina a propriedade DisplayInformation.AutoRotationPreferences como paisagem para impedir que a interface do usuário e o CaptureElement girem quando o usuário alterar a orientação do dispositivo. Para obter mais informações sobre como lidar com alterações de orientação do dispositivo, consulte Manipular a orientação do dispositivo com MediaCapture.

       private async Task StartPreviewAsync()
       {
           try
           {

               mediaCapture = new MediaCapture();
               await mediaCapture.InitializeAsync();

               displayRequest.RequestActive();
               DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape;
           }
           catch (UnauthorizedAccessException)
           {
               // This will be thrown if the user denied access to the camera in privacy settings
               ShowMessageToUser("The app was denied access to the camera");
               return;
           }

           try
           {
               PreviewControl.Source = mediaCapture;
               await mediaCapture.StartPreviewAsync();
               isPreviewing = true;
           }
           catch (System.IO.FileLoadException)
           {
               mediaCapture.CaptureDeviceExclusiveControlStatusChanged += _mediaCapture_CaptureDeviceExclusiveControlStatusChanged;
           }

       }

Lidar com alterações de controlo exclusivo

Como indicado na seção anterior, StartPreviewAsync lançará um FileLoadException se outro aplicativo tiver controle exclusivo do dispositivo de captura. A partir do Windows 10, versão 1703, você pode registrar um manipulador para o evento MediaCapture.CaptureDeviceExclusiveControlStatusChanged , que é gerado sempre que o status de controle exclusivo do dispositivo é alterado. No manipulador deste evento, verifique a propriedade MediaCaptureDeviceExclusiveControlStatusChangedEventArgs.Status para ver qual é o estado atual. Se o novo estado for SharedReadOnlyAvailable, então sabe que não pode iniciar a pré-visualização no momento e poderá querer atualizar a interface de utilizador para alertar. Se o novo estado for ExclusiveControlAvailable, podes tentar iniciar a visualização da câmara de novo.

private async void _mediaCapture_CaptureDeviceExclusiveControlStatusChanged(MediaCapture sender, MediaCaptureDeviceExclusiveControlStatusChangedEventArgs args)
{
    if (args.Status == MediaCaptureDeviceExclusiveControlStatus.SharedReadOnlyAvailable)
    {
        ShowMessageToUser("The camera preview can't be displayed because another app has exclusive access");
    }
    else if (args.Status == MediaCaptureDeviceExclusiveControlStatus.ExclusiveControlAvailable && !isPreviewing)
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            await StartPreviewAsync();
        });
    }
}

Desligue o fluxo de visualização

Quando terminar de usar o fluxo de visualização, você deve sempre desligar o fluxo e descartar corretamente os recursos associados para garantir que a câmera esteja disponível para outros aplicativos no dispositivo. As etapas necessárias para encerrar o fluxo de visualização são:

  • Se a câmera estiver visualizando no momento, chame StopPreviewAsync para interromper o fluxo de visualização. Uma exceção será lançada se você chamar StopPreviewAsync enquanto a visualização não estiver em execução.
  • Defina a propriedade Source do CaptureElement como null. Use CoreDispatcher.RunAsync para garantir que essa chamada seja executada no thread da interface do usuário.
  • Chame o método MediaCaptureDispose para liberar o objeto. Novamente, use CoreDispatcher.RunAsync para garantir que esta chamada seja executada na thread da UI.
  • Defina o MediaCapture variável membro como null.
  • Chame RequestRelease para permitir que o ecrã se desligue quando estiver inativo.
private async Task CleanupCameraAsync()
{
    if (mediaCapture != null)
    {
        if (isPreviewing)
        {
            await mediaCapture.StopPreviewAsync();
        }

        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            PreviewControl.Source = null;
            if (displayRequest != null)
            {
                displayRequest.RequestRelease();
            }

            mediaCapture.Dispose();
            mediaCapture = null;
        });
    }
    
}

Você deve desligar o fluxo de visualização quando o usuário navegar para fora da sua página, substituindo o método OnNavigatedFrom.

protected async override void OnNavigatedFrom(NavigationEventArgs e)
{
    await CleanupCameraAsync();
}

Você também deve desligar o fluxo de visualização corretamente quando seu aplicativo estiver suspendendo. Para fazer isso, registre um manipulador para o evento Application.Suspending no construtor da sua página.

public MainPage()
{
    this.InitializeComponent();

    Application.Current.Suspending += Application_Suspending;
}

Na Suspensão do manipulador de eventos, primeiro verifique se a página está a ser exibida no Frame do aplicativo comparando o tipo da página ao tipo atual da propriedade CurrentSourcePageType. Se a página não estiver atualmente sendo exibida, o evento OnNavigatedFrom já deve ter sido gerado e o fluxo de visualização deve ter sido encerrado. Se a página estiver sendo exibida no momento, obtenha um objeto SuspendingDeferral dos args de evento passados para o manipulador para garantir que o sistema não suspenda seu aplicativo até que o fluxo de visualização seja desligado. Depois de desligar o fluxo, chame o método Complete do adiamento para permitir que o sistema continue suspendendo seu aplicativo.

private async void Application_Suspending(object sender, SuspendingEventArgs e)
{
    // Handle global application events only if this page is active
    if (Frame.CurrentSourcePageType == typeof(MainPage))
    {
        var deferral = e.SuspendingOperation.GetDeferral();
        await CleanupCameraAsync();
        deferral.Complete();
    }
}