Esercitazione: Usare Visione di Azure AI per generare i metadati delle immagini in Archiviazione di Azure

In questa esercitazione si apprenderà come integrare il servizio Visione di Azure AI in un'app Web per generare i metadati per le immagini caricate. Questa operazione è utile per gli scenari di gestione delle risorse digitali (DAM), ad esempio se un'azienda vuole generare rapidamente didascalie descrittive o parole chiave ricercabili per tutte le immagini.

Si userà Visual Studio per scrivere un'app Web MVC che accetta immagini caricate dagli utenti e le archivia nell'archivio BLOB di Azure. Si apprenderà come leggere e scrivere BLOB in C# e usare i metadati di BLOB per aggiungere altre informazioni ai BLOB creati. Si invierà quindi ogni immagine caricata dall'utente all'API Visione di Azure AI per generare una didascalia e cercare i metadati per l'immagine. Si distribuirà infine l'app nel cloud usando Visual Studio.

Questa esercitazione illustra come:

  • Creare un account di archiviazione e contenitori di archiviazione usando il portale di Azure
  • Creare un'app Web in Visual Studio e distribuirla in Azure
  • Usare l'API Visione di Azure AI per estrarre informazioni dalle immagini
  • Allegare i metadati alle immagini di Archiviazione di Azure
  • Controllare i metadati delle immagini con Azure Storage Explorer

Suggerimento

La sezione Usare Visione di Azure AI per generare metadati riguarda soprattutto l'analisi delle immagini. Passare a questa sezione se si vuole capire l'integrazione dell'analisi delle immagini e un'applicazione stabilita.

Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare.

Prerequisiti

Creare un account di archiviazione

In questa sezione si usa il portale di Azure per creare un account di archiviazione. Si crea quindi una coppia di contenitori: uno per archiviare le immagini caricate dall'utente e un altro per archiviare le anteprime delle immagini generate dalle immagini caricate.

  1. Accedere al portale di Azure dal browser. Se viene chiesto di eseguire l'accesso, usare l'account Microsoft.

  2. Per creare un account di archiviazione, selezionare + Crea una risorsa nella barra multifunzione a sinistra. Quindi selezionare Archiviazione, quindi su Account di archiviazione.

    Creazione di un account di archiviazione

  3. Immettere un nome univoco per l'account di archiviazione nel campo Nome e assicurarsi che accanto al campo venga visualizzato un segno di spunta verde. Il nome è importante perché costituisce una parte dell'URL tramite cui si accede ai BLOB creati con questo account. Posizionare l'account di archiviazione in un nuovo gruppo di risorse denominato "IntellipixResources" e selezionare l'area più vicina. Per completare, selezionare il pulsante Rivedi e crea nella parte inferiore della schermata per creare il nuovo account di archiviazione.

    Nota

    I nomi degli account di archiviazione possono avere una lunghezza compresa tra 3 e 24 caratteri e contenere solo numeri e lettere minuscole. Inoltre, il nome immesso deve essere univoco all'interno di Azure. Se un altro utente ha scelto lo stesso nome, si riceverà una notifica che indica che il nome non è disponibile e verrà visualizzato un punto esclamativo rosso nel campo Nome.

    Specifica dei parametri per un nuovo account di archiviazione

  4. Selezionare Gruppi di risorse nella barra multifunzione a sinistra. Selezionare quindi il gruppo di risorse "IntellipixResources".

    Apertura del gruppo di risorse

  5. Nella scheda visualizzata per il gruppo di risorse selezionare l'account di archiviazione creato. Se l'account di archiviazione non è ancora presente, è possibile selezionare Aggiorna nella parte superiore della scheda finché l'account non viene visualizzato.

    Aprire il nuovo account di archiviazione

  6. Nella scheda dell'account di archiviazione selezionare BLOB per visualizzare l'elenco di contenitori associati a questo account.

    Pulsante Visualizzazione BLOB

  7. L'account di archiviazione non ha attualmente contenitori. Prima di poter creare un BLOB, è necessario creare un contenitore in cui archiviarlo. Selezionare + Contenitore per creare un nuovo contenitore. Digitare photos nel campo Nome e selezionare BLOB in Livello di accesso pubblico. Selezionare quindi OK per creare un contenitore denominato "photos".

    Per impostazione predefinita, i contenitori e il relativo contenuto sono privati. Se si seleziona BLOB come livello di accesso, i BLOB nel contenitore "photos" diventano accessibili pubblicamente, ma non rende pubblico il contenitore. Ciò è necessario perché le immagini archiviate nel contenitore "photos" verranno associate a collegamenti da un'app Web.

    Creare un contenitore

  8. Ripetere il passaggio precedente per creare un contenitore denominato "thumbnails", verificando anche in questo caso che l'opzione Livello di accesso pubblico per il contenitore sia impostata su BLOB.

  9. Verificare che entrambi i contenitori siano visualizzati nell'elenco di contenitori per questo account di archiviazione e che i nomi siano digitati correttamente.

    Nuovi contenitori

  10. Chiudere la schermata "Servizio BLOB". Selezionare Chiavi di accesso nel menu a sinistra della schermata dell'account di archiviazione e selezionare il pulsante Copia nella colonna CHIAVE per key1. Incollare questa chiave di accesso nell'editor di testo preferito per usarlo in un secondo momento.

    Copia della chiave di accesso

In questo modo è stato creato un account di archiviazione per contenere le immagini caricate nell'app da compilare e i contenitori in cui archiviare le immagini.

Eseguire Azure Storage Explorer

Azure Storage Explorer è uno strumento gratuito che fornisce un'interfaccia grafica per l'uso di Archiviazione di Azure nei PC che eseguono Windows, macOS e Linux. Offre la maggior parte delle stesse funzionalità del portale di Azure e altre funzionalità come la possibilità di visualizzare i metadati dei BLOB. In questa sezione viene utilizzato Microsoft Azure Storage Explorer per visualizzare i contenitori creati nella sezione precedente.

  1. Se Storage Explorer non è stato installato o per assicurarsi di eseguire la versione più recente, passare a http://storageexplorer.com/ e scaricare e installare l'app.

  2. Avviare Storage Explorer. Se viene chiesto di eseguire l'accesso, usare l'account Microsoft, ovvero lo stesso account usato per accedere al portale di Azure. Se nel riquadro sinistro di Storage Explorer non viene visualizzato l'account di archiviazione, selezionare il pulsante Gestisci account evidenziato di seguito e assicurarsi che sia l'account Microsoft che la sottoscrizione usata per creare l'account di archiviazione siano stati aggiunti a Storage Explorer.

    Gestione degli account in Storage Explorer

  3. Selezionare la piccola freccia accanto all'account di archiviazione per visualizzarne il contenuto e quindi selezionare la freccia accanto a Contenitori BLOB. Verificare che i contenitori creati siano visualizzati nell'elenco.

    Visualizzazione dei contenitori BLOB

I contenitori sono attualmente vuoti, ma la situazione cambierà non appena verrà distribuita l'app e verranno caricate le foto. L'installazione di Storage Explorer semplificherà la visualizzazione delle operazioni di scrittura dell'app nell'archivio BLOB.

Creare una nuova app Web in Visual Studio

In questa sezione si crea una nuova app Web in Visual Studio e si aggiungerà il codice per implementare le funzionalità di base necessarie per caricare immagini, scriverle nell'archivio BLOB e visualizzarle in una pagina Web.

  1. Avviare Visual Studio e usare il comando File -> Nuovo -> Progetto per creare un nuovo progetto di applicazione Web di Visual C# ASP.NET denominato "Intellipix" (abbreviazione di "Intelligent Pictures" [Immagini intelligenti]).

    Creazione di un nuovo progetto Applicazione Web.

  2. Nella finestra di dialogo "Nuova applicazione Web ASP.NET" verificare che MVC sia selezionato. Quindi, seleziona OK.

    Creazione di un nuovo progetto MVC ASP.NET

  3. Esaminare la struttura del progetto in Esplora soluzioni. Tra le altre cose, sono presenti una cartella denominata Controllers, contenente i controller MVC del progetto, e una cartella denominata Views, contenente le viste del progetto. Durante l'implementazione dell'applicazione si utilizzano gli asset disponibili in queste cartelle e altri.

    Il progetto mostrato in Esplora soluzioni

  4. Usare il comando Debug -> Avvia senza debug di Visual Studio (o premere CTRL+F5) per avviare l'applicazione nel browser. Ecco come appare l'applicazione allo stato attuale:

    Applicazione iniziale

  5. Chiudere il browser e tornare a Visual Studio. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto Intellipix e scegliere Gestisci pacchetti NuGet. Selezionare Sfoglia. Digitare imageresizer nella casella di ricerca e selezionare il pacchetto NuGet denominato ImageResizer. Infine, selezionare Installa per installare la versione stabile più recente del pacchetto. ImageResizer contiene API che verranno usate per creare anteprime di immagini dalle immagini caricate nell'app. Fare clic su OK per confermare le modifiche e accettare eventuali licenze presentate all'utente.

    Installazione di ImageResizer

  6. Ripetere questo processo per aggiungere il pacchetto NuGet denominato WindowsAzure.Storage al progetto. Questo pacchetto contiene le API per l'accesso ad Archiviazione di Azure dalle applicazioni .NET. Fare clic su OK per confermare le modifiche e accettare eventuali licenze presentate all'utente.

    Installazione di WindowsAzure.Storage

  7. Aprire Web.config e aggiungere l'istruzione seguente alla sezione <appSettings>, sostituendo ACCOUNT_NAME con il nome dell'account di archiviazione creato nella prima sezione e ACCOUNT_KEY con la chiave di accesso salvata.

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

    Importante

    Il file Web.config conterrà informazioni riservate come le chiavi di sottoscrizione e qualsiasi richiesta HTTP a un file con estensione config viene gestita dal motore di ASP.NET, che restituisce un messaggio "Questo tipo di pagina non viene gestita". Tuttavia, se un utente malintenzionato è in grado di trovare un altro exploit che consenta di visualizzare il contenuto di Web.config, sarà anche in grado di esporre tali informazioni. Vedere Protezione delle stringhe di connessione e altre informazioni di configurazione per altri passaggi che è possibile eseguire per proteggere ulteriormente i dati nel file Web.config.

  8. Aprire il file denominato _Layout.cshtml nella cartella Views/Shared del progetto. Nella riga 19 sostituire "Application name" con "Intellipix". La riga dovrebbe essere simile alla seguente:

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

    Nota

    In un progetto ASP.NET MVC, _Layout.cshtml è una vista speciale che funge da modello per altre viste. In genere si definisce il contenuto dell'intestazione e del piè di pagina comune a tutte le viste in questo file.

  9. Fare clic con il pulsante destro del mouse sulla cartella Models del progetto e usare il comando Aggiungi -> Classe... per aggiungere un file di classe denominato BlobInfo.cs alla cartella. Sostituire quindi la classe BlobInfo vuota con la definizione di classe seguente:

    public class BlobInfo
    {
        public string ImageUri { get; set; }
        public string ThumbnailUri { get; set; }
        public string Caption { get; set; }
    }
    
  10. Aprire HomeController.cs nella cartella Controllers del progetto e aggiungere le istruzioni using seguenti all'inizio del file:

    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. Sostituire il metodo Index in HomeController.cs con l'implementazione seguente:

    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();
    }
    

    Il nuovo metodo Index enumera i BLOB nel contenitore "photos" e passa una matrice di oggetti BlobInfo che rappresentano tali BLOB per la vista tramite proprietà ViewBag di ASP.NET MVC. Successivamente, si modificherà la vista per enumerare questi oggetti e visualizzare una raccolta di anteprime di foto. Le classi che verranno usate per accedere all'account di archiviazione ed enumerare i BLOB, ovvero CloudStorageAccount, CloudBlobClient e CloudBlobContainer, provengono dal pacchetto WindowsAzure.Storage installato tramite NuGet.

  12. Aggiungere il metodo seguente alla classe HomeController in 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");
    }
    

    Questo è il metodo chiamato quando si carica una foto. Archivia ogni immagine caricata come BLOB nel contenitore "photos", crea un'immagine di anteprima dall'immagine originale usando il pacchetto ImageResizer e archivia l'immagine di anteprima come BLOB nel contenitore "thumbnails".

  13. Aprire Index.cshmtl nella cartella Views/Home del progetto e sostituirne il contenuto con il codice e il markup seguenti:

    @{
        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>
    }
    

    Il linguaggio usato qui è Razor, che consente di incorporare codice eseguibile nel markup HTML. L'istruzione @foreach al centro del file enumera gli oggetti BlobInfo passati dal controller in ViewBag e crea elementi <img> HTML in base a tali oggetti. La proprietà src di ogni elemento viene inizializzata con l'URI del BLOB contenente l'anteprima dell'immagine.

  14. Scaricare e decomprimere il file photos.zip dal repository di dati di esempio di GitHub. Si tratta di una selezione di varie foto che è possibile usare per testare l'app.

  15. Salvare le modifiche e premere CTRL+F5 per avviare l'applicazione nel browser. Selezionare quindi Carica una foto e caricare una delle immagini scaricate. Verificare che nella pagina venga visualizzata una versione di anteprima della foto.

    Intellipix con una foto caricata

  16. Caricare alcune altre immagini dalla cartella photos. Verificare che vengano visualizzate anche nella pagina:

    Intellipix con tre foto caricate

  17. Fare clic con il pulsante destro del mouse nel browser e selezionare Visualizza origine pagina per visualizzare il codice sorgente per la pagina. Trovare gli elementi <img> che rappresentano le anteprime dell'immagine. Osservare che gli URL assegnati alle immagini fanno riferimento direttamente ai BLOB nell'archivio BLOB. Ciò è dovuto al fatto che per il contenitore il parametro Livello di accesso pubblico è stato impostato su BLOB e ciò rende i BLOB accessibili pubblicamente.

  18. Tornare ad Azure Storage Explorer (o riavviarlo se non è in esecuzione) e selezionare il contenitore "photos" nell'account di archiviazione. Il numero di BLOB nel contenitore deve essere uguale al numero di foto caricate. Fare doppio clic su uno dei BLOB per scaricarlo e visualizzare la relativa immagine archiviata.

    Contenuto del contenitore

  19. Aprire il contenitore"thumbnails" in Storage Explorer. Aprire uno dei BLOB per visualizzare le immagini di anteprima generate dai caricamenti delle immagini.

Nell'app non è ancora disponibile un modo per visualizzare le immagini originali caricate. Idealmente, è possibile selezionare l'anteprima di un'immagine per visualizzare l'immagine originale. Questa funzionalità verrà aggiunta successivamente.

Aggiungere un lightbox per la visualizzazione delle foto

In questa sezione si usa una libreria JavaScript open source gratuita per aggiungere un visualizzatore lightbox che consente agli utenti di visualizzare le immagini originali caricate anziché solo le relative anteprime. Sono disponibili file predefiniti. Sarà sufficiente integrarli nel progetto e apportare piccole modifiche a Index.cshtml.

  1. Scaricare i file lightbox.css e lightbox.js dal repository di codice GitHub.

  2. In Esplora soluzioni fare clic con il pulsante destro del mouse nella cartella Script del progetto e usare il comando Aggiungi -> Nuovo elemento per creare un file lightbox.js. Incollare il contenuto del file di esempio nel repository di codice GitHub.

  3. Fare clic con il pulsante destro del mouse nella cartella "Content" del progetto e usare il comando Aggiungi -> Nuovo elemento per creare un file lightbox.css. Incollare il contenuto del file di esempio nel repository di codice GitHub.

  4. Scaricare e decomprimere il file buttons.zip dal repository dei file di dati GitHub: https://github.com/Azure-Samples/cognitive-services-sample-data-files/tree/master/ComputerVision/storage-lab-tutorial. Dovrebbero essere presenti quattro immagini di pulsante.

  5. Fare clic con il pulsante destro del mouse nel progetto Intellipix in Esplora soluzioni e usare il comando Aggiungi -> Nuova cartella per aggiungere una cartella denominata "Images" al progetto.

  6. Fare clic con il pulsante destro del mouse nella cartella Images e usare il comando Aggiungi -> Elemento esistente... per importare le quattro immagini scaricate.

  7. Aprire BundleConfig.cs nella cartella "App_Start" del progetto. Aggiungere l'istruzione seguente al metodo RegisterBundles in BundleConfig.cs:

    bundles.Add(new ScriptBundle("~/bundles/lightbox").Include(
              "~/Scripts/lightbox.js"));
    
  8. Nello stesso metodo trovare l'istruzione che crea StyleBundle da "~/Content/css" e aggiungere lightbox.css all'elenco dei fogli di stile nel bundle. Ecco l'istruzione modificata:

    bundles.Add(new StyleBundle("~/Content/css").Include(
              "~/Content/bootstrap.css",
              "~/Content/site.css",
              "~/Content/lightbox.css"));
    
  9. Aprire _Layout.cshtml nella cartella Views/Shared del progetto e aggiungere l'istruzione seguente subito prima dell'istruzione @RenderSection nella parte inferiore:

    @Scripts.Render("~/bundles/lightbox")
    
  10. L'attività finale consiste nell'incorporare il visualizzatore lightbox nella home page. A tale scopo, aprire Index.cshtml (si trova nella cartella Views/Home del progetto) e sostituire il ciclo @foreach con il seguente:

    @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. Salvare le modifiche e premere CTRL+F5 per avviare l'applicazione nel browser. Quindi selezionare una delle immagini caricate in precedenza. Verificare che venga visualizzato un lightbox, contenente una vista ingrandita dell'immagine.

    Immagine ingrandita

  12. Selezionare la X nell'angolo in basso a destra del lightbox per chiuderlo.

A questo punto è possibile visualizzare le immagini caricate. Il passaggio successivo consiste nell'eseguire altre operazioni con queste immagini.

Usare Visione di Azure AI per generare metadati

Creare una risorsa di Visione

È necessario creare una risorsa Visione artificiale per l'accesso al servizio Visione di Azure AI.

  1. Passare al portale di Azure e creare una risorsa di Visione artificiale.

  2. Passare quindi al menu per il gruppo di risorse e selezionare la risorsa visione creata. Copiare l'URL sotto Endpoint in qualsiasi punto sia possibile recuperarlo facilmente in seguito. Selezionare quindi Mostra chiavi di accesso.

    Pagina del portale di Azure con l'URL endpoint e il collegamento delle chiavi di accesso evidenziato

    Nota

    Le nuove risorse create dopo il 1° luglio 2019 useranno nomi di sottodomini personalizzati. Per altre informazioni e per un elenco completo degli endpoint a livello di area, vedere Nomi di sottodomini personalizzati per Servizi di Azure AI.

  3. Nella finestra successiva, copiare il valore della CHIAVE 1 negli Appunti.

    Finestra di dialogo Gestisci chiavi con il pulsante di copia evidenziato

Aggiungere le credenziali dell'API Visione di Azure AI

Quindi aggiungere le credenziali necessarie all’app in modo da poter accedere alle risorse di Visione.

Passare al file Web.config nella cartella radice del progetto. Aggiungere le istruzioni seguenti alla sezione <appSettings> del file, sostituendo VISION_KEY con la chiave copiata nel passaggio precedente e VISION_ENDPOINT con l'URL salvato nel passaggio precedente.

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

In Esplora soluzioni, fare clic con il pulsante destro del mouse sulla soluzione del progetto e scegliere Gestisci pacchetti NuGet. Nella finestra di dialogo Gestione pacchetti visualizzata selezionare Sfoglia, Includi versione preliminare e cercare Azure.AI.Vision.ImageAnalysis. Selezionare Installa.

Aggiungere il codice di generazione dei metadati

Successivamente, si aggiungerà il codice che usa il servizio Visione di Azure AI per creare i metadati per le immagini.

  1. Aprire il file HomeController.cs nella cartella controller del progetto e aggiungere le seguenti istruzioni using all'inizio del file:

    using Azure;
    using Azure.AI.Vision.ImageAnalysis;
    using System;
    
  2. Passare quindi al metodo Upload, che converte e carica le immagini nell'archiviazione BLOB. Aggiungere il codice seguente immediatamente dopo il blocco che inizia con // Generate a thumbnail (o alla fine del processo di creazione di BLOB dell'immagine). Questo codice accetta il BLOB contenente l'immagine (photo) e usa Visione di Azure AI per generare una descrizione per quell'immagine. L'API Visione di Azure AI genera inoltre un elenco di parole chiave che si applicano all'immagine. Le parole chiave e la descrizione generate vengono archiviate nei metadati del BLOB per poterle recuperare in un secondo momento.

    // 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. Passare quindi al metodo Index nello stesso file. Questo metodo enumera i BLOB delle immagini archiviate nel contenitore BLOB di destinazione (come istanze di IListBlobItem) e li passa alla visualizzazione dell'applicazione. Sostituire il blocco foreach in questo metodo con il codice seguente. Questo codice chiama CloudBlockBlob.FetchAttributes per ottenere i metadati allegati di ogni BLOB. Estrae la descrizione generata dal computer (caption) dai metadati e la aggiunge all'oggetto BlobInfo, che viene passato alla vista.

    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
            });
        }
    }
    

Testare l'app

Salvare le modifiche in Visual Studio e premere CTRL+F5 per avviare l'applicazione nel browser. Usa l'app per caricare altre immagini, dal set di foto scaricato o da una cartella personalizzata. Quando si passa il cursore su una delle nuove immagini nella vista, verrà visualizzata una finestra di descrizione comando contenente la didascalia dell'immagine generata dal computer.

Didascalia generata dal computer

Per visualizzare tutti i metadati allegati, usare Azure Storage Explorer per visualizzare il contenitore di archiviazione in uso per le immagini. Fare clic con il pulsante destro del mouse su un BLOB qualsiasi nel contenitore e scegliere Proprietà. Nella finestra di dialogo, verrà visualizzato un elenco di coppie chiave-valore. La descrizione dell'immagine generata dal computer viene archiviata nell'elemento Caption e le parole chiave di ricerca vengono archiviate in Tag0, Tag1 e così via. Al termine, selezionare Annulla per chiudere la finestra di dialogo.

Finestra di dialogo Proprietà immagine, con i tag dei metadati elencati

Aggiungere la ricerca all'app

In questa sezione si aggiunge una casella di ricerca alla home page, in modo da consentire agli utenti di eseguire ricerche di parole chiave nelle immagini caricate. Le parole chiave sono parole generate dall'API Visione di Azure AI e archiviate nei metadati BLOB.

  1. Aprire Index.cshtml nella cartella Views/Home del progetto e aggiungere le istruzioni seguenti all'elemento vuoto <div> con l'attributo class="col-sm-4 pull-right":

    @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>
    }
    

    Questi codice e markup aggiungono una casella di ricerca e un pulsante Cerca alla home page.

  2. Aprire HomeController.cs nella cartella Controllers del progetto e aggiungere il metodo seguente alla classe HomeController:

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

    Questo è il metodo chiamato quando l'utente seleziona il pulsante Cerca aggiunto nel passaggio precedente. Aggiorna la pagina e include un parametro di ricerca nell'URL.

  3. Sostituire il metodo Index con l'implementazione seguente:

    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();
    }
    

    Si noti che il metodo Index ora accetta un parametro id contenente il valore digitato dall'utente nella casella di ricerca. Un parametro id vuoto o mancante indica che tutte le foto devono essere visualizzate.

  4. Aggiungere il metodo helper seguente alla 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;
    }
    

    Questo metodo viene chiamato dal metodo Index per determinare se le parole chiave dei metadati associati a un BLOB di immagini specifico contengono il termine di ricerca immesso dall'utente.

  5. Avviare di nuovo l'applicazione e caricare più foto. È possibile usare foto personalizzate e non solo quelle fornite con l'esercitazione.

  6. Digitare una parola chiave, ad esempio "river" nella casella di ricerca. Quindi selezionare il pulsante Cerca.

    Esecuzione di una ricerca

  7. I risultati della ricerca variano a seconda di ciò che è stato digitato e delle immagini caricate. Il risultato deve tuttavia restituire un elenco filtrato di immagini le cui parole chiave presenti nei metadati includono tutte o parte della parola chiave digitata.

    Risultati della ricerca

  8. Selezionare il pulsante Indietro del browser per visualizzare di nuovo tutte le immagini.

Il programma è quasi completo. A questo punto, è possibile distribuire l'app nel cloud.

Distribuire l'app in Azure

In questa sezione si distribuisce l'app in Azure da Visual Studio. È possibile consentire a Visual Studio di creare automaticamente un'app Web di Azure, in modo che non sia necessario crearla separatamente nel portale di Azure.

  1. In Visual Studio fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e scegliere Pubblica... nel menu di scelta rapida. Assicurarsi che Servizio app di Microsoft Azure e Crea nuovo siano selezionati e quindi selezionare il pulsante Pubblica.

    Pubblicazione dell'app

  2. Nella finestra di dialogo successiva selezionare il gruppo di risorse "IntellipixResources" in Gruppo di risorse. Selezionare il pulsante Nuovo... accanto a "Piano di servizio app" e creare un nuovo piano di servizio app nella stessa posizione selezionata per l'account di archiviazione in Creare un account di archiviazione, accettando tutte le impostazioni predefinite. Per completare l'operazione, selezionare il pulsante Crea.

    Creare un'app Web di Azure

  3. Dopo alcuni istanti, l'app verrà visualizzata in una finestra del browser. Prendere nota dell'URL visualizzato nella barra degli indirizzi. L'app non è più in esecuzione in locale; è infatti sul Web, dove è raggiungibile pubblicamente.

    Il prodotto finito

Se si apportano modifiche all'app e si vuole eseguire il push delle modifiche nel Web, rieseguire il processo di pubblicazione. È comunque possibile testare le modifiche in locale prima della pubblicazione sul Web.

Pulire le risorse

Per continuare a lavorare sull'app Web, vedere la sezione Passaggi successivi. Se non si intende continuare a usare questa applicazione, è necessario eliminare tutte le risorse specifiche delle app. Per eliminare le risorse, è sufficiente eliminare il gruppo di risorse che contiene la sottoscrizione di Archiviazione di Azure e la risorsa Visione. Verranno rimossi l'account di archiviazione, i BLOB in esso caricati e la risorsa del servizio app necessaria per connettersi con l'app Web ASP.NET.

Per eliminare il gruppo di risorse, aprire la scheda Gruppi di risorse nel portale, passare al gruppo di risorse usato per questo progetto e selezionare Elimina gruppo di risorse nella parte superiore della visualizzazione. Viene chiesto di digitare il nome del gruppo di risorse per confermare che si vuole eliminarlo. Dopo l'eliminazione, non è più possibile recuperare un gruppo di risorse.

Passaggi successivi

In Azure è possibile sviluppare ulteriormente l'app Intellipix. Ad esempio, è possibile aggiungere il supporto per l'autenticazione degli utenti e l'eliminazione di foto e anziché costringere l'utente ad attendere che Servizi di Azure AI elabori una foto dopo un caricamento, è possibile usare Funzioni di Azure per chiamare l'API Visione di Azure AI in modo asincrono ogni volta che un'immagine viene aggiunta all'archiviazione BLOB. È anche possibile eseguire un numero qualsiasi di altre operazioni di analisi delle immagini sull'immagine, descritte nella panoramica.