Tutorial: Usar o Azure AI Vision para gerar metadados de imagem no Armazenamento do Azure

Neste tutorial, você aprenderá como integrar o serviço Azure AI Vision em um aplicativo Web para gerar metadados para imagens carregadas. Isso é útil para cenários de gerenciamento de ativos digitais (DAM), como se uma empresa quiser gerar rapidamente legendas descritivas ou palavras-chave pesquisáveis para todas as suas imagens.

Você usará o Visual Studio para escrever um aplicativo Web MVC que aceite imagens carregadas por usuários e armazene as imagens no armazenamento de blobs do Azure. Você aprenderá a ler e escrever blobs em C# e a usar metadados de blob para anexar informações adicionais aos blobs criados. Em seguida, você enviará cada imagem carregada pelo usuário para a API do Azure AI Vision para gerar uma legenda e pesquisar metadados para a imagem. Finalmente, você pode implantar o aplicativo na nuvem usando o Visual Studio.

Este tutorial mostrar-lhe como:

  • Criar uma conta de armazenamento e contêineres de armazenamento usando o portal do Azure
  • Criar um aplicativo Web no Visual Studio e implantá-lo no Azure
  • Usar a API do Azure AI Vision para extrair informações de imagens
  • Anexar metadados a imagens do Armazenamento do Azure
  • Verificar metadados de imagem usando o Gerenciador de Armazenamento do Azure

Gorjeta

A seção Usar o Azure AI Vision para gerar metadados é mais relevante para a Análise de Imagem. Vá para lá se você quiser apenas ver como a Análise de Imagem é integrada em um aplicativo estabelecido.

Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.

Pré-requisitos

Criar uma conta de armazenamento

Nesta seção, você usará o portal do Azure para criar uma conta de armazenamento. Em seguida, você criará um par de contêineres: um para armazenar imagens carregadas pelo usuário e outro para armazenar miniaturas de imagens geradas a partir das imagens carregadas.

  1. Entre no portal do Azure em seu navegador. Se lhe for pedido para iniciar sessão, faça-o utilizando a sua conta Microsoft.

  2. Para criar uma conta de armazenamento, selecione + Criar um recurso na faixa de opções à esquerda. Em seguida, selecione Armazenamento, seguido por Conta de armazenamento.

    Creating a storage account

  3. Insira um nome exclusivo para a conta de armazenamento no campo Nome e verifique se uma marca de seleção verde aparece ao lado dela. O nome é importante, porque faz parte do URL através do qual os blobs criados sob esta conta são acedidos. Coloque a conta de armazenamento em um novo grupo de recursos chamado "IntellipixResources" e selecione a região mais próxima de você. Termine selecionando o botão Revisar + criar na parte inferior da tela para criar a nova conta de armazenamento.

    Nota

    Os nomes das contas de armazenamento podem ter de 3 a 24 caracteres e conter apenas números e letras minúsculas. Além disso, o nome inserido deve ser exclusivo no Azure. Se outra pessoa tiver escolhido o mesmo nome, você será notificado de que o nome não está disponível com um ponto de exclamação vermelho no campo Nome .

    Specifying parameters for a new storage account

  4. Selecione Grupos de recursos na faixa de opções à esquerda. Em seguida, selecione o grupo de recursos "IntellipixResources".

    Opening the resource group

  5. Na guia que se abre para o grupo de recursos, selecione a conta de armazenamento que você criou. Se a conta de armazenamento ainda não estiver lá, você poderá selecionar Atualizar na parte superior da guia até que ela apareça.

    Opening the new storage account

  6. Na guia da conta de armazenamento, selecione Blobs para exibir uma lista de contêineres associados a essa conta.

    Viewing blobs button

  7. A conta de armazenamento atualmente não tem contêineres. Antes de criar um blob, você deve criar um contêiner para armazená-lo. Selecione + Contêiner para criar um novo contêiner. Digite photos no campo Nome e selecione Blob como o nível de acesso público. Em seguida, selecione OK para criar um contêiner chamado "fotos".

    Por padrão, os contêineres e seu conteúdo são privados. Selecionar Blob como o nível de acesso torna os blobs no contêiner "fotos" acessíveis publicamente, mas não torna o contêiner em si público. Isso é o que você quer porque as imagens armazenadas no contêiner "fotos" serão vinculadas a partir de um aplicativo Web.

    Creating a

  8. Repita a etapa anterior para criar um contêiner chamado "miniaturas", garantindo mais uma vez que o nível de acesso público do contêiner esteja definido como Blob.

  9. Confirme se ambos os contêineres aparecem na lista de contêineres dessa conta de armazenamento e se os nomes estão escritos corretamente.

    The new containers

  10. Feche a tela "Serviço de Blob". Selecione Teclas de acesso no menu do lado esquerdo da tela da conta de armazenamento e, em seguida, selecione o botão Copiar ao lado de KEY para key1. Cole esta chave de acesso no seu editor de texto favorito para uso posterior.

    Copying the access key

Agora você criou uma conta de armazenamento para armazenar imagens carregadas no aplicativo que você vai criar e contêineres para armazenar as imagens.

Executar o Gerenciador de Armazenamento do Azure

O Azure Storage Explorer é uma ferramenta gratuita que fornece uma interface gráfica para trabalhar com o Armazenamento do Azure em PCs com Windows, macOS e Linux. Ele fornece a maior parte da mesma funcionalidade que o portal do Azure e oferece outros recursos, como a capacidade de exibir metadados de blob. Nesta seção, você usará o Gerenciador de Armazenamento do Microsoft Azure para exibir os contêineres criados na seção anterior.

  1. Se ainda não instalou o Explorador de Armazenamento ou se pretende certificar-se de que está a executar a versão mais recente, aceda a http://storageexplorer.com/ Transferir e instalar.

  2. Inicie o Gerenciador de Armazenamento. Se lhe for pedido para iniciar sessão, faça-o utilizando a sua conta Microsoft, a mesma que utilizou para iniciar sessão no portal do Azure. Se não vir a conta de armazenamento no painel esquerdo do Explorador de Armazenamento, selecione o botão Gerir Contas realçado abaixo e certifique-se de que tanto a sua conta Microsoft como a subscrição utilizada para criar a conta de armazenamento foram adicionadas ao Explorador de Armazenamento .

    Managing accounts in Storage Explorer

  3. Selecione a pequena seta ao lado da conta de armazenamento para exibir seu conteúdo e, em seguida, selecione a seta ao lado de Contêineres de Blob. Confirme se os contêineres criados aparecem na lista.

    Viewing blob containers

Os contêineres estão vazios no momento, mas isso mudará quando seu aplicativo for implantado e você começar a carregar fotos. Ter o Storage Explorer instalado tornará mais fácil para você ver o que seu aplicativo grava no armazenamento de blobs.

Criar um novo aplicativo Web no Visual Studio

Nesta seção, você criará um novo aplicativo Web no Visual Studio e adicionará código para implementar a funcionalidade básica necessária para carregar imagens, gravá-las no armazenamento de blob e exibi-las em uma página da Web.

  1. Inicie o Visual Studio e use o comando File - New ->> Project para criar um novo projeto Visual C# ASP.NET Web Application chamado "Intellipix" (abreviação de "Intelligent Pictures").

    Creating a new Web Application project

  2. Na caixa de diálogo "Novo aplicativo Web ASP.NET", verifique se MVC está selecionado. Em seguida, selecione OK.

    Creating a new ASP.NET MVC project

  3. Reserve um momento para revisar a estrutura do projeto no Gerenciador de Soluções. Entre outras coisas, há uma pasta chamada Controllers que contém os controladores MVC do projeto e uma pasta chamada Views que contém as exibições do projeto. Você trabalhará com ativos nessas pastas e em outras à medida que implementa o aplicativo.

    The project shown in Solution Explorer

  4. Use o comando Debug -> Start Without Debugging do Visual Studio (ou pressione Ctrl+F5) para iniciar o aplicativo em seu navegador. Veja como o aplicativo parece em seu estado atual:

    The initial application

  5. Feche o navegador e retorne ao Visual Studio. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto Intellipix e selecione Gerenciar pacotes NuGet.... Selecione Procurar. Em seguida, digite imageresizer na caixa de pesquisa e selecione o pacote NuGet chamado ImageResizer. Finalmente, selecione Instalar para instalar a versão estável mais recente do pacote. ImageResizer contém APIs que você usará para criar miniaturas de imagens a partir das imagens carregadas no aplicativo. OK quaisquer alterações e aceite quaisquer licenças que lhe sejam apresentadas.

    Installing ImageResizer

  6. Repita esse processo para adicionar o pacote NuGet chamado WindowsAzure.Storage ao projeto. Este pacote contém APIs para acessar o Armazenamento do Azure a partir de aplicativos .NET. OK quaisquer alterações e aceite quaisquer licenças que lhe sejam apresentadas.

    Installing WindowsAzure.Storage

  7. Abra Web.config e adicione a seguinte instrução à <appSettings> seção, substituindo-ACCOUNT_NAME pelo nome da conta de armazenamento que você criou na primeira seção e ACCOUNT_KEY com a chave de acesso que você salvou.

    <add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=ACCOUNT_NAME;AccountKey=ACCOUNT_KEY" />
    

    Importante

    O arquivo Web.config destina-se a armazenar informações confidenciais, como suas chaves de assinatura, e qualquer solicitação HTTP para um arquivo com a extensão .config é tratada pelo mecanismo de ASP.NET, que retorna uma mensagem "Este tipo de página não é servido". No entanto, se um invasor conseguir encontrar alguma outra exploração que permita visualizar o conteúdo do Web.config, ele poderá expor essas informações. Consulte Protegendo cadeias de conexão e outras informações de configuração para obter etapas adicionais que você pode tomar para proteger ainda mais seus dados Web.config .

  8. Abra o arquivo chamado _Layout.cshtml na pasta Views/Shared do projeto. Na linha 19, altere "Nome do aplicativo" para "Intellipix". A linha deve ter esta aparência:

    @Html.ActionLink("Intellipix", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
    

    Nota

    Em um projeto MVC ASP.NET, _Layout.cshtml é uma exibição especial que serve como modelo para outras exibições. Normalmente, você define o conteúdo de cabeçalho e rodapé que é comum a todos os modos de exibição neste arquivo.

  9. Clique com o botão direito do mouse na pasta Models do projeto e use o comando Add -> Class... para adicionar um arquivo de classe chamado BlobInfo.cs à pasta. Em seguida, substitua a classe BlobInfo vazia pela seguinte definição de classe:

    public class BlobInfo
    {
        public string ImageUri { get; set; }
        public string ThumbnailUri { get; set; }
        public string Caption { get; set; }
    }
    
  10. Abra HomeController.cs da pasta Controllers do projeto e adicione as seguintes using instruções à parte superior do arquivo:

    using ImageResizer;
    using Intellipix.Models;
    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Blob;
    using System.Configuration;
    using System.Threading.Tasks;
    using System.IO;
    
  11. Substitua o método Index no HomeController.cs pela seguinte implementação:

    public ActionResult Index()
    {
        // Pass a list of blob URIs in ViewBag
        CloudStorageAccount account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);
        CloudBlobClient client = account.CreateCloudBlobClient();
        CloudBlobContainer container = client.GetContainerReference("photos");
        List<BlobInfo> blobs = new List<BlobInfo>();
    
        foreach (IListBlobItem item in container.ListBlobs())
        {
            var blob = item as CloudBlockBlob;
    
            if (blob != null)
            {
                blobs.Add(new BlobInfo()
                {
                    ImageUri = blob.Uri.ToString(),
                    ThumbnailUri = blob.Uri.ToString().Replace("/photos/", "/thumbnails/")
                });
            }
        }
    
        ViewBag.Blobs = blobs.ToArray();
        return View();
    }
    

    O novo método Index enumera os blobs no "photos" contêiner e passa uma matriz de objetos BlobInfo que representam esses blobs para a exibição por meio ASP.NET propriedade ViewBag do MVC. Mais tarde, você modificará a exibição para enumerar esses objetos e exibir uma coleção de miniaturas de fotos. As classes que você usará para acessar sua conta de armazenamento e enumerar os blobs — CloudStorageAccount, CloudBlobClient e CloudBlobContainer vêm do pacote WindowsAzure.Storage instalado por meio do NuGet.

  12. Adicione o seguinte método à classe HomeController no HomeController.cs:

    [HttpPost]
    public async Task<ActionResult> Upload(HttpPostedFileBase file)
    {
        if (file != null && file.ContentLength > 0)
        {
            // Make sure the user selected an image file
            if (!file.ContentType.StartsWith("image"))
            {
                TempData["Message"] = "Only image files may be uploaded";
            }
            else
            {
                try
                {
                    // Save the original image in the "photos" container
                    CloudStorageAccount account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);
                    CloudBlobClient client = account.CreateCloudBlobClient();
                    CloudBlobContainer container = client.GetContainerReference("photos");
                    CloudBlockBlob photo = container.GetBlockBlobReference(Path.GetFileName(file.FileName));
                    await photo.UploadFromStreamAsync(file.InputStream);
    
                    // Generate a thumbnail and save it in the "thumbnails" container
                    using (var outputStream = new MemoryStream())
                    {
                        file.InputStream.Seek(0L, SeekOrigin.Begin);
                        var settings = new ResizeSettings { MaxWidth = 192 };
                        ImageBuilder.Current.Build(file.InputStream, outputStream, settings);
                        outputStream.Seek(0L, SeekOrigin.Begin);
                        container = client.GetContainerReference("thumbnails");
                        CloudBlockBlob thumbnail = container.GetBlockBlobReference(Path.GetFileName(file.FileName));
                        await thumbnail.UploadFromStreamAsync(outputStream);
                    }
                }
                catch (Exception ex)
                {
                    // In case something goes wrong
                    TempData["Message"] = ex.Message;
                }
            }
        }
    
        return RedirectToAction("Index");
    }
    

    Este é o método que é chamado quando você carrega uma foto. Ele armazena cada imagem carregada como um blob no contêiner, cria uma imagem em miniatura da imagem original usando o ImageResizer pacote e armazena "photos" a imagem em miniatura como um blob no "thumbnails" contêiner.

  13. Abra Index.cshmtl na pasta Views/Home do projeto e substitua seu conteúdo pelo seguinte código e marcação:

    @{
        ViewBag.Title = "Intellipix Home Page";
    }
    
    @using Intellipix.Models
    
    <div class="container" style="padding-top: 24px">
        <div class="row">
            <div class="col-sm-8">
                @using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
                {
                    <input type="file" name="file" id="upload" style="display: none" onchange="$('#submit').click();" />
                    <input type="button" value="Upload a Photo" class="btn btn-primary btn-lg" onclick="$('#upload').click();" />
                    <input type="submit" id="submit" style="display: none" />
                }
            </div>
            <div class="col-sm-4 pull-right">
            </div>
        </div>
    
        <hr />
    
        <div class="row">
            <div class="col-sm-12">
                @foreach (BlobInfo blob in ViewBag.Blobs)
                {
                    <img src="@blob.ThumbnailUri" width="192" title="@blob.Caption" style="padding-right: 16px; padding-bottom: 16px" />
                }
            </div>
        </div>
    </div>
    
    @section scripts
    {
        <script type="text/javascript" language="javascript">
            if ("@TempData["Message"]" !== "") {
                alert("@TempData["Message"]");
            }
        </script>
    }
    

    A linguagem usada aqui é o Razor, que permite incorporar código executável na marcação HTML. A @foreach instrução no meio do arquivo enumera os objetos BlobInfo passados do controlador em ViewBag e cria elementos HTML <img> a partir deles. A src propriedade de cada elemento é inicializada com o URI do blob que contém a miniatura da imagem.

  14. Baixe e descompacte o arquivo photos.zip do repositório de dados de exemplo do GitHub. Esta é uma variedade de fotos diferentes que você pode usar para testar o aplicativo.

  15. Salve suas alterações e pressione Ctrl+F5 para iniciar o aplicativo em seu navegador. Em seguida, selecione Carregar uma foto e carregue uma das imagens que você baixou. Confirme se uma versão em miniatura da foto aparece na página.

    Intellipix with one photo uploaded

  16. Carregue mais algumas imagens da sua pasta de fotos . Confirme se eles também aparecem na página:

    Intellipix with three photos uploaded

  17. Clique com o botão direito do rato no seu browser e selecione Ver origem da página para ver o código-fonte da página. Encontre os <img> elementos que representam as miniaturas da imagem. Observe que as URLs atribuídas às imagens se referem diretamente a blobs no armazenamento de blobs. Isso ocorre porque você define o nível de acesso público dos contêineres como Blob, o que torna os blobs dentro acessíveis publicamente.

  18. Retorne ao Gerenciador de Armazenamento do Azure (ou reinicie-o se não o deixou em execução) e selecione o "photos" contêiner em sua conta de armazenamento. O número de blobs no contêiner deve ser igual ao número de fotos carregadas. Clique duas vezes em um dos blobs para baixá-lo e ver a imagem armazenada no blob.

    Contents of the

  19. Abra o "thumbnails" contêiner no Gerenciador de Armazenamento. Abra um dos blobs para visualizar as imagens em miniatura geradas a partir dos carregamentos de imagens.

O aplicativo ainda não oferece uma maneira de visualizar as imagens originais que você carregou. Idealmente, a seleção de uma miniatura de imagem deve exibir a imagem original. Você adicionará esse recurso em seguida.

Adicionar uma lightbox para visualizar fotos

Nesta seção, você usará uma biblioteca JavaScript gratuita e de código aberto para adicionar um visualizador lightbox que permite que os usuários vejam as imagens originais que carregaram (em vez de apenas as miniaturas das imagens). Os arquivos são fornecidos para você. Tudo o que você precisa fazer é integrá-los ao projeto e fazer uma pequena modificação no Index.cshtml.

  1. Baixe os arquivos lightbox.css e lightbox.js do repositório de código do GitHub.

  2. No Gerenciador de Soluções, clique com o botão direito do mouse na pasta Scripts do projeto e use o comando Adicionar -> Novo Item... para criar um arquivo lightbox.js. Cole o conteúdo do arquivo de exemplo no repositório de código do GitHub.

  3. Clique com o botão direito do mouse na pasta "Conteúdo" do projeto e use o comando Adicionar -> Novo Item... para criar um arquivo lightbox.css . Cole o conteúdo do arquivo de exemplo no repositório de código do GitHub.

  4. Baixe e descompacte o arquivo buttons.zip do repositório de arquivos de dados do GitHub: https://github.com/Azure-Samples/cognitive-services-sample-data-files/tree/master/ComputerVision/storage-lab-tutorial. Você deve ter imagens de quatro botões.

  5. Clique com o botão direito do mouse no projeto Intellipix no Gerenciador de Soluções e use o comando Adicionar -> Nova Pasta para adicionar uma pasta chamada "Imagens" ao projeto.

  6. Clique com o botão direito do mouse na pasta Imagens e use o comando Adicionar -> Item Existente... para importar as quatro imagens baixadas.

  7. Abra BundleConfig.cs na pasta "App_Start" do projeto. Adicione a seguinte instrução ao RegisterBundles método em BundleConfig.cs:

    bundles.Add(new ScriptBundle("~/bundles/lightbox").Include(
              "~/Scripts/lightbox.js"));
    
  8. No mesmo método, localize a instrução que cria um StyleBundle de "~/Content/css" e adicione lightbox.css à lista de folhas de estilo no pacote. Aqui está a declaração modificada:

    bundles.Add(new StyleBundle("~/Content/css").Include(
              "~/Content/bootstrap.css",
              "~/Content/site.css",
              "~/Content/lightbox.css"));
    
  9. Abra _Layout.cshtml na pasta Views/Shared do projeto e adicione a seguinte instrução logo antes da @RenderSection instrução na parte inferior:

    @Scripts.Render("~/bundles/lightbox")
    
  10. A tarefa final é incorporar o visualizador lightbox na página inicial. Para fazer isso, abra Index.cshtml (está na pasta Views/Home do projeto) e substitua o @foreach loop por este:

    @foreach (BlobInfo blob in ViewBag.Blobs)
    {
        <a href="@blob.ImageUri" rel="lightbox" title="@blob.Caption">
            <img src="@blob.ThumbnailUri" width="192" title="@blob.Caption" style="padding-right: 16px; padding-bottom: 16px" />
        </a>
    }
    
  11. Salve suas alterações e pressione Ctrl+F5 para iniciar o aplicativo em seu navegador. Em seguida, selecione uma das imagens que carregou anteriormente. Confirme se uma lightbox aparece e mostra uma vista ampliada da imagem.

    An enlarged image

  12. Selecione o X no canto inferior direito da lightbox para descartá-lo.

Agora você tem uma maneira de ver as imagens que você carregou. O próximo passo é fazer mais com essas imagens.

Usar o Azure AI Vision para gerar metadados

Criar um recurso Visão

Você precisará criar um recurso de Visão Computacional para sua conta do Azure; este recurso gerencia seu acesso ao serviço Azure AI Vision do Azure.

  1. Siga as instruções em Criar um recurso de serviços de IA do Azure para criar um recurso multisserviço ou um recurso Visão.

  2. Em seguida, vá para o menu do seu grupo de recursos e selecione o recurso Visão que você criou. Copie o URL em Endpoint para algum lugar onde você possa recuperá-lo facilmente em um momento. Em seguida, selecione Mostrar chaves de acesso.

    Azure portal page with the endpoint URL and access keys link outlined

    Nota

    Novos recursos criados após 1º de julho de 2019 usarão nomes de subdomínio personalizados. Para obter mais informações e uma lista completa de pontos de extremidade regionais, consulte Nomes de subdomínio personalizados para serviços de IA do Azure.

  3. Na janela seguinte, copie o valor da CHAVE 1 para a área de transferência.

    Manage keys dialog, with the copy button outlined

Adicionar credenciais do Azure AI Vision

Em seguida, você adicionará as credenciais necessárias ao seu aplicativo para que ele possa acessar os recursos do Vision.

Navegue até o arquivo Web.config na raiz do projeto. Adicione as instruções a seguir à <appSettings> seção do arquivo, substituindo VISION_KEY pela chave copiada na etapa anterior e VISION_ENDPOINT pela URL salva na etapa anterior.

<add key="SubscriptionKey" value="VISION_KEY" />
<add key="VisionEndpoint" value="VISION_ENDPOINT" />

no Gerenciador de Soluções. Clique com o botão direito do mouse na solução do projeto e selecione Gerenciar pacotes NuGet. No gerenciador de pacotes aberto, selecione Procurar, marque Incluir pré-lançamento e procure Azure.AI.Vision.ImageAnalysis. Selecione Instalar.

Adicionar código de geração de metadados

Em seguida, você adicionará o código que realmente usa o serviço Azure AI Vision para criar metadados para imagens.

  1. Abra o arquivo HomeController.cs na pasta Controllers do projeto e adicione as seguintes using instruções na parte superior do arquivo:

    using Azure;
    using Azure.AI.Vision.ImageAnalysis;
    using System;
    
  2. Em seguida, vá para o método Upload , este método converte e carrega imagens para armazenamento de blobs. Adicione o seguinte código imediatamente após o bloco que começa com // Generate a thumbnail (ou no final do seu processo de criação de blob de imagem). Esse código usa o blob que contém a imagem (photo) e usa o Azure AI Vision para gerar uma descrição para essa imagem. A API do Azure AI Vision também gera uma lista de palavras-chave que se aplicam à imagem. A descrição gerada e as palavras-chave são armazenadas nos metadados do blob para que possam ser recuperadas posteriormente.

    // create a new ImageAnalysisClient
    ImageAnalysisClient client = new ImageAnalysisClient(
            new Uri(Environment.GetEnvironmentVariable(ConfigurationManager.AppSettings["VisionEndpoint"])),
            new AzureKeyCredential(ConfigurationManager.AppSettings["SubscriptionKey"]));
    
    VisualFeatures = visualFeatures = VisualFeatures.Caption | VisualFeatures.Tags;
    
    ImageAnalysisOptions analysisOptions = new ImageAnalysisOptions()
    {
        GenderNeutralCaption = true,
        Language = "en",
    };
    
    Uri imageURL = new Uri(photo.Uri.ToString());
    
    ImageAnalysisResult  result = client.Analyze(imageURL,visualFeatures,analysisOptions);
    
    // Record the image description and tags in blob metadata
    photo.Metadata.Add("Caption", result.Caption.Text);
    
    for (int i = 0; i < result.Tags.Values.Count; i++)
    {
        string key = String.Format("Tag{0}", i);
        photo.Metadata.Add(key, result.Tags.Values[i]);
    }
    
    await photo.SetMetadataAsync();
    
  3. Em seguida, vá para o método Index no mesmo arquivo. Esse método enumera os blobs de imagem armazenados no contêiner de blob de destino (como instâncias IListBlobItem ) e os passa para a exibição do aplicativo. Substitua o bloco neste método com o foreach código a seguir. Esse código chama CloudBlockBlob.FetchAttributes para obter os metadados anexados de cada blob. Ele extrai a descrição gerada por computador (caption) dos metadados e a adiciona ao objeto BlobInfo , que é passado para a exibição.

    foreach (IListBlobItem item in container.ListBlobs())
    {
        var blob = item as CloudBlockBlob;
    
        if (blob != null)
        {
            blob.FetchAttributes(); // Get blob metadata
            var caption = blob.Metadata.ContainsKey("Caption") ? blob.Metadata["Caption"] : blob.Name;
    
            blobs.Add(new BlobInfo()
            {
                ImageUri = blob.Uri.ToString(),
                ThumbnailUri = blob.Uri.ToString().Replace("/photos/", "/thumbnails/"),
                Caption = caption
            });
        }
    }
    

Testar a aplicação

Salve suas alterações no Visual Studio e pressione Ctrl+F5 para iniciar o aplicativo em seu navegador. Use o aplicativo para carregar mais algumas imagens, seja do conjunto de fotos que você baixou ou de sua própria pasta. Quando você passa o cursor sobre uma das novas imagens na exibição, uma janela de dica de ferramenta deve aparecer e exibir a legenda gerada pelo computador para a imagem.

The computer-generated caption

Para exibir todos os metadados anexados, use o Gerenciador de Armazenamento do Azure para exibir o contêiner de armazenamento que você está usando para imagens. Clique com o botão direito do mouse em qualquer um dos blobs no contêiner e selecione Propriedades. Na caixa de diálogo, você verá uma lista de pares chave-valor. A descrição da imagem gerada por computador é armazenada no item Caption, e as palavras-chave de pesquisa são armazenadas em Tag0, Tag1e assim por diante. Quando terminar, selecione Cancelar para fechar a caixa de diálogo.

Image properties dialog window, with metadata tags listed

Adicionar pesquisa à aplicação

Nesta seção, você adicionará uma caixa de pesquisa à página inicial, permitindo que os usuários façam pesquisas por palavras-chave nas imagens que carregaram. As palavras-chave são as geradas pela API do Azure AI Vision e armazenadas em metadados de blob.

  1. Abra Index.cshtml na pasta Views/Home do projeto e adicione as seguintes instruções ao elemento vazio <div> com o class="col-sm-4 pull-right" atributo:

    @using (Html.BeginForm("Search", "Home", FormMethod.Post, new { enctype = "multipart/form-data", @class = "navbar-form" }))
    {
        <div class="input-group">
            <input type="text" class="form-control" placeholder="Search photos" name="term" value="@ViewBag.Search" style="max-width: 800px">
            <span class="input-group-btn">
                <button class="btn btn-primary" type="submit">
                    <i class="glyphicon glyphicon-search"></i>
                </button>
            </span>
        </div>
    }
    

    Esse código e marcação adicionam uma caixa de pesquisa e um botão Pesquisar à página inicial.

  2. Abra HomeController.cs na pasta Controllers do projeto e adicione o seguinte método à classe HomeController:

    [HttpPost]
    public ActionResult Search(string term)
    {
        return RedirectToAction("Index", new { id = term });
    }
    

    Este é o método que é chamado quando o usuário seleciona o botão Pesquisar adicionado na etapa anterior. Ele atualiza a página e inclui um parâmetro de pesquisa no URL.

  3. Substitua o método Index pela seguinte implementação:

    public ActionResult Index(string id)
    {
        // Pass a list of blob URIs and captions in ViewBag
        CloudStorageAccount account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);
        CloudBlobClient client = account.CreateCloudBlobClient();
        CloudBlobContainer container = client.GetContainerReference("photos");
        List<BlobInfo> blobs = new List<BlobInfo>();
    
        foreach (IListBlobItem item in container.ListBlobs())
        {
            var blob = item as CloudBlockBlob;
    
            if (blob != null)
            {
                blob.FetchAttributes(); // Get blob metadata
    
                if (String.IsNullOrEmpty(id) || HasMatchingMetadata(blob, id))
                {
                    var caption = blob.Metadata.ContainsKey("Caption") ? blob.Metadata["Caption"] : blob.Name;
    
                    blobs.Add(new BlobInfo()
                    {
                        ImageUri = blob.Uri.ToString(),
                        ThumbnailUri = blob.Uri.ToString().Replace("/photos/", "/thumbnails/"),
                        Caption = caption
                    });
                }
            }
        }
    
        ViewBag.Blobs = blobs.ToArray();
        ViewBag.Search = id; // Prevent search box from losing its content
        return View();
    }
    

    Observe que o método Index agora aceita um parâmetro id que contém o valor que o usuário digitou na caixa de pesquisa. Um parâmetro vazio ou ausente id indica que todas as fotos devem ser exibidas.

  4. Adicione o seguinte método auxiliar à classe HomeController :

    private bool HasMatchingMetadata(CloudBlockBlob blob, string term)
    {
        foreach (var item in blob.Metadata)
        {
            if (item.Key.StartsWith("Tag") && item.Value.Equals(term, StringComparison.InvariantCultureIgnoreCase))
                return true;
        }
    
        return false;
    }
    

    Esse método é chamado pelo método Index para determinar se as palavras-chave de metadados anexadas a um determinado blob de imagem contêm o termo de pesquisa que o usuário inseriu.

  5. Inicie o aplicativo novamente e carregue várias fotos. Sinta-se livre para usar suas próprias fotos, não apenas as fornecidas com o tutorial.

  6. Digite uma palavra-chave como "rio" na caixa de pesquisa. Em seguida, selecione o botão Pesquisar .

    Performing a search

  7. Os resultados da pesquisa variam consoante o que escreveu e as imagens que carregou. Mas o resultado deve ser uma lista filtrada de imagens cujas palavras-chave de metadados incluam toda ou parte da palavra-chave que você digitou.

    Search results

  8. Selecione o botão Voltar do navegador para exibir todas as imagens novamente.

Está quase a terminar. É hora de implantar o aplicativo na nuvem.

Implementar a aplicação no Azure

Nesta seção, você implantará o aplicativo no Azure a partir do Visual Studio. Você permitirá que o Visual Studio crie um Aplicativo Web do Azure para você, evitando que você precise entrar no portal do Azure e criá-lo separadamente.

  1. Clique com o botão direito do mouse no projeto no Gerenciador de Soluções e selecione Publicar... no menu de contexto. Verifique se o Serviço de Aplicativo do Microsoft Azure e Criar Novo estão selecionados e selecione obotão Publicar.

    Publishing the app

  2. Na caixa de diálogo seguinte, selecione o grupo de recursos "IntellipixResources" em Grupo de recursos. Selecione o botão Novo... ao lado de "Plano do Serviço de Aplicativo" e crie um novo Plano do Serviço de Aplicativo no mesmo local selecionado para a conta de armazenamento em Criar uma conta de armazenamento, aceitando os padrões em todos os outros lugares. Termine selecionando o botão Criar .

    Creating an Azure Web App

  3. Depois de alguns momentos, o aplicativo aparecerá em uma janela do navegador. Observe o URL na barra de endereço. O aplicativo não está mais sendo executado localmente; está na Web, onde é acessível publicamente.

    The finished product!

Se você fizer alterações no aplicativo e quiser enviar as alterações para a Web, passe pelo processo de publicação novamente. Você ainda pode testar suas alterações localmente antes de publicar na Web.

Clean up resources (Limpar recursos)

Se quiser continuar a trabalhar na sua aplicação Web, consulte a secção Próximos passos . Se não planeia continuar a utilizar esta aplicação, deve eliminar todos os recursos específicos da aplicação. Para excluir recursos, você pode excluir o grupo de recursos que contém sua assinatura do Armazenamento do Azure e o recurso Visão. Isso removerá a conta de armazenamento, os blobs carregados nela e o recurso do Serviço de Aplicativo necessário para se conectar ao aplicativo Web ASP.NET.

Para excluir o grupo de recursos, abra a guia Grupos de recursos no portal, navegue até o grupo de recursos usado para este projeto e selecione Excluir grupo de recursos na parte superior da exibição. Ser-lhe-á pedido que escreva o nome do grupo de recursos para confirmar que pretende eliminá-lo. Uma vez excluído, um grupo de recursos não pode ser recuperado.

Próximos passos

Há muito mais que você pode fazer para usar o Azure e desenvolver ainda mais seu aplicativo Intellipix. Por exemplo, você pode adicionar suporte para autenticar usuários e excluir fotos e, em vez de forçar o usuário a aguardar que os serviços de IA do Azure processem uma foto após um carregamento, você pode usar o Azure Functions para chamar a API do Azure AI Vision de forma assíncrona cada vez que uma imagem é adicionada ao armazenamento de blobs. Você também pode fazer qualquer número de outras operações de Análise de Imagem na imagem, descritas na visão geral.