Olá comunidade 100loop! Estou muito feliz por estar escrevendo o meu primeiro post para vocês. Para quem não me conhece, eu me chamo André Alves de Lima. Eu trabalho com desenvolvimento de aplicativos desktop utilizando a plataforma Microsoft desde 2005. Fui um dos líderes da comunidade .NETRaptors alguns anos atrás, e normalmente escrevo sobre o meu aprendizado no meu blog: Talking about Software Development, Technology and more. A fim de expandir meus horizontes e aumentar o meu “reach“, pensei em fazer uns “guest posts” aqui na comunidade 100loop. A princípio pretendo escrever aqui aproximadamente uma vez por mês, e o assunto será normalmente desenvolvimento de “aplicativos modernos” para o Windows 8 (plataforma WinRT). Nesse meu primeiro post, quero abordar o acesso à webcam em aplicativos para a Windows Store.

O motivo pelo qual eu escolhi esse tema foi que, algumas semanas atrás, eu escrevi um artigo no meu blog sobre o acesso à webcam em C# (para aplicativos desktop, não Windows Store). Se vocês conferirem o artigo, vocês perceberão que acessar a webcam em aplicativos desktop (com Windows Forms ou WPF, por exemplo) não é uma tarefa trivial. Para conseguir essa façanha, temos que utilizar bibliotecas externas que geralmente não têm uma API muito amigável. Aí eu pensei: será que em aplicativos para a Windows Store nós também precisamos fazer esses tipos de malabarismos para acessar a webcam? Por sorte, a Microsoft resolveu esse problema e adicionou o suporte à webcam diretamente na plataforma WinRT.

Para demonstrar essa funcionalidade, vamos começar criando um projeto do tipo “Blank App (Windows)“, que se encontra dentro da categoria “Store Apps => Windows Apps“. O primeiro ajuste que temos que fazer nesse projeto é adicionar o suporte à webcam no manifesto da aplicação. Para isso, abra o arquivo “Package.appxmanifest“, vá até a aba “Capabilities” e marque a opção “Webcam“:

Feito isso, é hora de irmos até o XAML da “MainPage” para adicionarmos um “Button” (que fará o acionamento a webcam) e um “Image” (que exibirá a imagem que foi capturada pela webcam):

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <Button x:Name="WebcamButton"
                    Content="Webcam"
                    VerticalAlignment="Top"
                    Margin="50"
                    Click="WebcamButton_Click" />
            <Image x:Name="WebcamImage"
                   Width="800"
                   Height="450"
                   Stretch="UniformToFill" />
        </StackPanel>
    </Grid>

No “code behind” da MainPage, adicione o código para o evento “Click” do botão. Obviamente poderíamos utilizar o padrão MVVM criando um “Command” para o clique do botão. Mas, para não complicar, vamos implementar o código diretamente no evento “Click” do botão:

        private async void WebcamButton_Click(object sender, RoutedEventArgs e)
        {
            var cameraCapture = new Windows.Media.Capture.CameraCaptureUI();
            var file = await cameraCapture.CaptureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.Photo);
            if (file != null)
            {
                
                var stream = await file.OpenReadAsync();
                Windows.UI.Xaml.Media.Imaging.BitmapImage image = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
                image.SetSourceAsync(stream);
                WebcamImage.Source = image;
            }
        }

Como vocês podem observar, a classe responsável por exibir a ferramenta de captura da webcam é a CameraCaptureUI. Além do método utilizado para fazer a captura (CaptureFileAsync), essa classe possui duas propriedades que podemos utilizar para configurarmos as propriedades da captura de fotos ou vídeos: PhotoSettings e VideoSettings. Nas configurações da foto, você pode definir, por exemplo, a resolução máxima da foto, o formato da foto (jpeg ou png) e se a ferramenta de cropping estará habilitada:

Execute a aplicação, clique no botão “Webcam” e veja que o Windows exibirá uma mensagem de confirmação perguntando se você permite o acesso à webcam:

Ao confirmar o acesso, o Windows exibirá a janela de captura de foto:

Após realizar e confirmar a captura, a imagem é exibida no controle Image da nossa página:

E se quisermos salvar a imagem em disco? Para isso, basta utilizarmos o método “CopyAsync” do arquivo retornado pela captura da webcam:

        private async void WebcamButton_Click(object sender, RoutedEventArgs e)
        {
            var cameraCapture = new Windows.Media.Capture.CameraCaptureUI();
            
            var file = await cameraCapture.CaptureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.Photo);
            if (file != null)
            {
                var stream = await file.OpenReadAsync();
                Windows.UI.Xaml.Media.Imaging.BitmapImage image = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
                image.SetSourceAsync(stream);
                WebcamImage.Source = image;
                
                file.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder, "capture.jpg", Windows.Storage.NameCollisionOption.ReplaceExisting);
            }
        }

Como vocês podem perceber, o método “CopyAsync” recebe como parâmetro o diretório onde o arquivo deverá ser salvo (no nosso caso utilizamos a pasta local do aplicativo), o nome do arquivo (“capture.jpg“) e a ação que deve ser realizada caso o arquivo destino já exista (no nosso caso escolhemos substituir o arquivo existente).

Ao executarmos a aplicação com essa alteração e tirarmos uma foto, o arquivo será armazenado na pasta local do aplicativo, justamente como definimos. Mas, onde é que fica a pasta local dos aplicativos do Windows 8? Elas ficam dentro da pasta “%LocalAppData%\Packages“, onde você encontrará uma pasta para cada aplicativo moderno instalado no seu computador:

Para descobrir qual é a pasta do seu aplicativo, abra o manifesto da aplicação, vá até a categoria “Packaging” e observe a propriedade “Package Name“. Você deve encontrar uma pasta dentro de “%LocalAppData%\Packages” começando com o mesmo conteúdo do “Package Name” da sua aplicação. E, dentro da subpasta “LocalState“, você encontrará a foto que foi salva pelo nosso aplicativo:

E se quisermos avançar um passo e perguntar para o usuário em qual diretório ele quer salvar a foto? Para isso podemos utilizar a classe FileSavePicker. Ao chamarmos o método PickSaveFileAsync, o Windows exibirá um diálogo para que o usuário possa selecionar o local onde ele quer salvar a captura. No exemplo abaixo, configuramos o diretório inicial como sendo o Desktop e bloqueamos a extensão do arquivo para “jpg“, uma vez que esse é o formato padrão utilizado pela webcam nos aplicativos para a Windows Store:

        private async void WebcamButton_Click(object sender, RoutedEventArgs e)
        {
            var cameraCapture = new Windows.Media.Capture.CameraCaptureUI();
            
            var file = await cameraCapture.CaptureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.Photo);
            if (file != null)
            {
                var stream = await file.OpenReadAsync();
                Windows.UI.Xaml.Media.Imaging.BitmapImage image = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
                image.SetSourceAsync(stream);
                WebcamImage.Source = image;
                
                Windows.Storage.Pickers.FileSavePicker filePicker = new Windows.Storage.Pickers.FileSavePicker();
                filePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
                filePicker.DefaultFileExtension = ".jpg";
                filePicker.FileTypeChoices.Add("JPG", new string[] { ".jpg" });
                var pickedFile = await filePicker.PickSaveFileAsync();
                file.CopyAndReplaceAsync(pickedFile);
            }
        }

Muito mais simples do que as manobras que tive que fazer para acessar a webcam através de um aplicativo Windows Forms, concorda?

E com isso concluo o meu primeiro artigo aqui no 100loop. Espero que vocês tenham gostado! Deixe um comentário logo abaixo contando pra gente o que você achou desse artigo.

Como comentei anteriormente, espero escrever aproximadamente um artigo por mês aqui na comunidade 100loop. Enquanto o próximo não chega, convido vocês a visitarem o meu site, onde vocês podem encontrar outros artigos relacionados ao desenvolvimento de aplicativos desktop com o a plataforma Microsoft.

Até a próxima!

André Lima

Image by Maik Meid used under Creative Commons
https://www.flickr.com/photos/frnetz/14448977472