Tutorial: Uso de Computer Vision para generar metadatos de imágenes en Azure Storage
En este tutorial, aprenderá a integrar el servicio Azure Computer Vision en una aplicación web para generar metadatos para las imágenes cargadas. Esto resulta útil para los escenarios de administración de activos digitales (DAM); por ejemplo, si una empresa quiere generar rápidamente leyendas descriptivas o palabras clave de búsqueda para todas sus imágenes.
Usará Visual Studio para escribir una aplicación web MVC que acepte imágenes cargadas por los usuarios y las almacene en Azure Blob Storage. Aprenderá a leer y escribir blobs en C# y a usar los metadatos del blob para adjuntar información adicional a los blobs que cree. A continuación, enviará cada imagen cargada por el usuario a Computer Vision API para generar un título y buscar metadatos para la imagen. Por último, puede implementar la aplicación en la nube mediante Visual Studio.
En este tutorial se muestra cómo realizar las siguientes acciones:
- Crear una cuenta de almacenamiento y contenedores de almacenamiento mediante Azure Portal
- Crear una aplicación web en Visual Studio e implementarla en Azure
- Usar Computer Vision API para extraer información de las imágenes
- Adjuntar metadatos a imágenes de Azure Storage
- Comprobar los metadatos de las imágenes con el Explorador de Azure Storage
Sugerencia
La sección Uso de Computer Vision para generar metadatos es más pertinente para el análisis de imágenes. Vaya a dicha sección si solo desea ver cómo se integra el análisis de imágenes en una aplicación establecida.
Si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.
Prerrequisitos
- Visual Studio 2017 Community Edition, o cualquier versión superior, con las cargas de trabajo "Desarrollo de ASP.NET y web" y "Desarrollo de Azure" instaladas.
- La herramienta Explorador de Azure Storage instalada.
Crear una cuenta de almacenamiento
En esta sección, utilizará Azure Portal para crear una cuenta de almacenamiento. A continuación, creará un par de contenedores: uno para almacenar las imágenes cargadas por el usuario y otro para almacenar las miniaturas de imagen generadas a partir de las imágenes cargadas.
En el explorador, abra Azure Portal. Si se le pide que inicie sesión, hágalo con su cuenta Microsoft.
Para crear una cuenta de almacenamiento, haga clic en + Crear un recurso en la cinta de opciones de la izquierda. A continuación, haga clic en Almacenamiento y luego en Cuenta de almacenamiento.
Escriba un nombre único para la cuenta de almacenamiento en el campo Nombre y asegúrese de que se muestre una marca de verificación verde junto a él. El nombre es importante, ya que forma una parte de la dirección URL mediante la cual se accede a los blobs creados en esta cuenta. Coloque la cuenta de almacenamiento en un nuevo grupo de recursos llamado "IntellipixResources" y seleccione la región más cercana. Para finalizar, haga clic en el botón Revisar y crear situado en la parte inferior de la pantalla para crear la nueva cuenta de almacenamiento.
Nota
Los nombres de las cuentas de almacenamiento pueden tener entre 3 y 24 caracteres y solo pueden incluir números y letras en minúscula. Además, el nombre que escriba debe ser único en Azure. Si alguien ha elegido el mismo nombre, se le notificará que el nombre no está disponible con un signo de exclamación rojo en el campo Nombre.
Haga clic en Grupos de recursos en la cinta de opciones de la izquierda. A continuación, haga clic en el grupo de recursos "IntellipixResources".
En la pestaña que se abre para el grupo de recursos, haga clic en la cuenta de almacenamiento que ha creado. Si la cuenta de almacenamiento aún no aparece, puede hacer clic en Actualizar en la parte superior de la pestaña hasta que aparezca.
En la pestaña de la cuenta de almacenamiento, haga clic en Blobs para ver una lista de contenedores asociados a esta cuenta.
Actualmente, la cuenta de almacenamiento no tiene contenedores. Antes de poder crear un blob, debe crear un contenedor para almacenarlo. Haga clic en + Contenedor para crear un nuevo contenedor. Escriba
photos
en el campo Nombre y seleccione Blob en el campo Nivel de acceso público. A continuación, haga clic en Aceptar para crear un contenedor llamado "photos".De manera predeterminada, los contenedores y su contenido son privados. Al seleccionar Blob como nivel de acceso, los blobs del contenedor "photos" son accesibles públicamente, pero no hacen que el propio contenedor sea público. Esto es lo que quiere, porque las imágenes almacenadas en el contenedor "photos" se vincularán desde una aplicación web.
Repita el paso anterior para crear un contenedor llamado "thumbnails". Una vez más, asegúrese de que el campo Nivel de acceso público del contenedor esté establecido en Blob.
Confirme que ambos contenedores se muestren en la lista de contenedores de esta cuenta de almacenamiento y que los nombres estén escritos correctamente.
Cierre la pantalla "Blob service". Haga clic en Claves de acceso en el menú del lado izquierdo de la pantalla de la cuenta de almacenamiento y, a continuación, haga clic en el botón Copiar situado junto a CLAVE para key1. Pegue esta clave de acceso en su editor de texto favorito para su uso posterior.
Ahora ha creado una cuenta de almacenamiento para almacenar las imágenes cargadas en la aplicación que va a crear y contenedores en los que almacenar las imágenes.
Ejecución del Explorador de Azure Storage
El Explorador de Azure Storage es una herramienta gratuita que proporciona una interfaz gráfica para trabajar con Azure Storage en equipos que ejecutan Windows, macOS y Linux. Proporciona la mayor parte de la misma funcionalidad que Azure Portal y ofrece otras características, como la capacidad de ver los metadatos de los blobs. En esta sección, usará el Explorador de Microsoft Azure Storage para ver los contenedores que ha creado en la sección anterior.
Si no ha instalado el Explorador de Storage o desea asegurarse de que está ejecutando la versión más reciente, vaya a http://storageexplorer.com/, descárguelo e instálelo.
Inicie el Explorador de Storage. Si se le pide que inicie sesión, hágalo con su cuenta Microsoft, la misma que usó para iniciar sesión en Azure Portal. Si no ve la cuenta de almacenamiento en el panel izquierdo del Explorador de Storage, haga clic en el botón Administrar cuentas resaltado a continuación y asegúrese de que tanto la cuenta Microsoft como la suscripción usada para crear la cuenta de almacenamiento se hayan agregado al Explorador de Storage.
Haga clic en la flecha pequeña situada junto a la cuenta de almacenamiento para mostrar su contenido y, a continuación, haga clic en la flecha situada junto a Contenedores de blobs. Confirme que los contenedores que ha creado se muestren en la lista.
Los contenedores están vacíos actualmente, pero esto cambiará una vez que se implemente la aplicación y empiece a cargar fotos. Tener el Explorador de Storage instalado le permitirá ver fácilmente lo que la aplicación escribe en Blob Storage.
Creación de una aplicación web en Visual Studio
En esta sección, creará una nueva aplicación web en Visual Studio y agregará código para implementar la funcionalidad básica necesaria para cargar imágenes, escribirlas en Blob Storage y mostrarlas en una página web.
Inicie Visual Studio y use el comando Archivo -> Nuevo -> Proyecto para crear un nuevo proyecto de aplicación web ASP.NET de Visual C# llamado "Intellipix" (abreviatura de "Imágenes inteligentes").
En el cuadro de diálogo "Nueva aplicación web ASP.NET", asegúrese de que esté seleccionado MVC. A continuación, haga clic en Aceptar.
Tómese un momento para revisar la estructura del proyecto en el Explorador de soluciones. Entre otras cosas, hay una carpeta llamada Controllers (Controladores) que contiene los controladores MVC del proyecto y una carpeta llamada Views (Vistas) que contiene las vistas del proyecto. Trabajará con los recursos de estas carpetas y otras a medida que implemente la aplicación.
Use el comando Depurar -> Iniciar sin depurar de Visual Studio (o pulse Ctrl+F5) para iniciar la aplicación en el explorador. Este es el aspecto de la aplicación en su estado actual:
Cierre el explorador y vuelva a Visual Studio. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto Intellipix y seleccione Administrar paquetes NuGet... . Haga clic en Examinar. A continuación, escriba
imageresizer
en el cuadro de búsqueda y seleccione el paquete NuGet llamado ImageResizer. Por último, haga clic en Instalar para instalar la versión estable más reciente del paquete. ImageResizer contiene las API que va a utilizar para crear miniaturas de imágenes a partir de las imágenes cargadas en la aplicación. Acepte los cambios y acepte las licencias que se le presenten.Repita este proceso para agregar el paquete NuGet llamado WindowsAzure.Storage al proyecto. Este paquete contiene las API para acceder a Azure Storage desde aplicaciones de .NET. Acepte los cambios y acepte las licencias que se le presenten.
Abra el archivo Web.config y agregue la siguiente instrucción a la sección
<appSettings>
, reemplazando ACCOUNT_NAME por el nombre de la cuenta de almacenamiento que creó en la primera sección y ACCOUNT_KEY por la clave de acceso que guardó.<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=ACCOUNT_NAME;AccountKey=ACCOUNT_KEY" />
Importante
El archivo Web.config está diseñado para contener información confidencial, como las claves de suscripción, y cualquier solicitud HTTP a un archivo con la extensión .config se controla mediante el motor de ASP.NET, que devuelve un mensaje que indica que "Este tipo de página no se proporciona". Sin embargo, si un atacante puede encontrar otra vulnerabilidad de seguridad que le permita ver el contenido del archivo Web.config, podrá exponer esa información. Consulte Protección de cadenas de conexión y otra información de configuración para conocer los pasos adicionales que puede seguir para proteger aún más los datos de Web.config.
Abra el archivo llamado _Layout.cshtml en la carpeta Views/Shared del proyecto. En la línea 19, cambie "Nombre de la aplicación" a "Intellipix". La línea debe tener este aspecto:
@Html.ActionLink("Intellipix", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
Nota
En un proyecto MVC de ASP.NET, el archivo _Layout.cshtml es una vista especial que actúa como plantilla para otras vistas. Normalmente, en este archivo se define el contenido del encabezado y el pie de página que es común a todas las vistas.
Haga clic con el botón derecho en la carpeta Models del proyecto y use el comando Agregar -> Clase... para agregar un archivo de clase llamado BlobInfo.cs a la carpeta. A continuación, reemplace la clase vacía BlobInfo por la siguiente definición de clase:
public class BlobInfo { public string ImageUri { get; set; } public string ThumbnailUri { get; set; } public string Caption { get; set; } }
Abra el archivo HomeController.cs, que encontrará en la carpeta Controllers (Controladores) del proyecto, y agregue las siguientes instrucciones
using
al principio del mismo:using ImageResizer; using Intellipix.Models; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; using System.Configuration; using System.Threading.Tasks; using System.IO;
Reemplace el método Index del archivo HomeController.cs por la siguiente implementación:
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(); }
El nuevo método Index enumera los blobs del contenedor
"photos"
y pasa una matriz de objetos BlobInfo que representan esos blobs en la vista mediante la propiedad ViewBag de MVC de ASP.NET. Más adelante, modificará la vista para enumerar estos objetos y mostrar una colección de miniaturas de fotos. Las clases que usará para acceder a la cuenta de almacenamiento y enumerar los blobs (CloudStorageAccount, CloudBlobClient y CloudBlobContainer) proceden del paquete WindowsAzure.Storage que instaló mediante NuGet.Agregue el método siguiente a la clase HomeController en el archivo 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 es el método al que se llama al cargar una foto. Almacena cada imagen cargada como un blob en el contenedor
"photos"
, crea una imagen en miniatura a partir de la imagen original mediante el paqueteImageResizer
y almacena la imagen en miniatura como un blob en el contenedor"thumbnails"
.Abra el archivo Index.cshmtl de la carpeta Views/Home del proyecto y reemplace su contenido por el código y marcado siguientes:
@{ 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> }
El lenguaje que se usa aquí es Razor, que permite insertar código ejecutable en el marcado HTML. La instrucción
@foreach
hacia la mitad del archivo enumera los objetos BlobInfo pasados desde el controlador en ViewBag y crea elementos<img>
de HTML a partir de ellos. La propiedadsrc
de cada elemento se inicializa con el identificador URI del blob que contiene la miniatura de la imagen.Descargue y descomprima el archivo photos.zip del repositorio de datos de ejemplo de GitHub. Se trata de una variedad de fotos diferentes que puede usar para probar la aplicación.
Guarde los cambios y pulse Ctrl+F5 para iniciar la aplicación en el explorador. A continuación, haga clic en Upload a Photo (Cargar una foto) y cargue una de las imágenes que ha descargado. Confirme que se muestre una versión en miniatura de la foto en la página.
Upload algunas imágenes más de la carpeta photos. Confirme que también aparecen en la página:
Haga clic con el botón derecho en el explorador y seleccione Ver código fuente de la página para ver el código fuente de la página. Busque los elementos
<img>
que representan las miniaturas de las imágenes. Observe que las direcciones URL asignadas a las imágenes hacen referencia directamente a los blobs de Blob Storage. Esto se debe a que ha establecido el Nivel de acceso público de los contenedores en Blob, lo que hace que se pueda acceder públicamente a los blobs que se encuentran dentro.Vuelva al Explorador de Azure Storage (o reinícielo si no lo dejó en ejecución) y seleccione el contenedor
"photos"
en la cuenta de almacenamiento. El número de blobs del contenedor debe ser igual al número de fotos que ha cargado. Haga doble clic en uno de los blobs para descargarlo y ver la imagen almacenada en el blob.Abra el contenedor
"thumbnails"
en el Explorador de Storage. Abra uno de los blobs para ver las imágenes en miniatura generadas a partir de las cargas de imágenes.
La aplicación aún no ofrece una manera de ver las imágenes originales que ha cargado. Lo ideal es hacer clic en una miniatura de imagen para mostrar la imagen original. Agregará esa característica a continuación.
Adición de un elemento lightbox para ver fotos
En esta sección, usará una biblioteca gratuita de JavaScript de código abierto para agregar un visor lightbox que permita a los usuarios ver las imágenes originales que han cargado (en lugar de solo las miniaturas de imagen). Se le proporcionan los archivos. Todo lo que tiene que hacer es integrarlos en el proyecto y realizar una pequeña modificación en el archivo Index.cshtml.
Descargue los archivos lightbox.css y lightbox.js desde el repositorio de código de GitHub.
En el Explorador de soluciones, haga clic con el botón derecho en la carpeta Scripts del proyecto y use el comando Agregar -> Nuevo elemento... para crear el archivo lightbox.js. Pegue el contenido del archivo de ejemplo del repositorio de código de GitHub.
Haga clic con el botón derecho en la carpeta "Content" (Contenido) del proyecto y use el comando Agregar -> Nuevo elemento... para crear el archivo lightbox.css. Pegue el contenido del archivo de ejemplo del repositorio de código de GitHub.
Descargue y descomprima el archivo buttons.zip del repositorio de archivos de datos de GitHub: https://github.com/Azure-Samples/cognitive-services-sample-data-files/tree/master/ComputerVision/storage-lab-tutorial. Debe tener cuatro imágenes de botón.
Haga clic con el botón derecho en el proyecto Intellipix en el Explorador de soluciones y use el comando Agregar -> Nueva carpeta para agregar una carpeta llamada "Images" (Imágenes) al proyecto.
Haga clic con el botón derecho en la carpeta Images y use el comando Agregar -> Elemento existente... para importar las cuatro imágenes que descargó.
Abra el archivo BundleConfig.cs de la carpeta "App_Start" del proyecto. Agregue la siguiente instrucción al método
RegisterBundles
en el archivo BundleConfig.cs:bundles.Add(new ScriptBundle("~/bundles/lightbox").Include( "~/Scripts/lightbox.js"));
En el mismo método, busque la instrucción que crea un elemento
StyleBundle
a partir de "~/Content/css" y agregue lightbox.css a la lista de hojas de estilos de la agrupación. Esta es la instrucción modificada:bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/bootstrap.css", "~/Content/site.css", "~/Content/lightbox.css"));
Abra el archivo _Layout.cshtml de la carpeta Views/Shared del proyecto y agregue la siguiente instrucción justo antes de la instrucción
@RenderSection
cerca de la parte inferior:@Scripts.Render("~/bundles/lightbox")
La tarea final consiste en incorporar el visor lightbox en la página principal. Para ello, abra el archivo Index.cshtml (se encuentra en la carpeta Views/Home del proyecto) y reemplace el bucle
@foreach
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> }
Guarde los cambios y pulse Ctrl+F5 para iniciar la aplicación en el explorador. A continuación, haga clic en una de las imágenes que cargó anteriormente. Confirme que aparece un visor lightbox y que muestre una vista ampliada de la imagen.
Haga clic en la X de la esquina inferior derecha del visor lightbox para descartarlo.
Ahora tiene una manera de ver las imágenes que ha cargado. El siguiente paso es hacer más cosas con esas imágenes.
Uso de Computer Vision para generar metadatos
Creación de un recurso de Computer Vision
Deberá crear un recurso de Computer Vision para su cuenta de Azure; este recurso administra el acceso al servicio Computer Vision de Azure.
Siga las instrucciones que se indican en Creación de un recurso de Azure Cognitive Services para crear un recurso de Computer Vision.
Luego, vuelva al menú del grupo de recursos y haga clic en la suscripción de Computer Vision API que ha creado. Copie la dirección URL de Punto de conexión a cualquier lugar en que pueda recuperarla fácilmente en un momento. Luego, haga clic en Show access keys (Mostrar claves de acceso).
Nota
Los nuevos recursos creados después del 1 de julio de 2019 usarán nombres de subdominio personalizados. Para más información y para obtener una lista completa de los puntos de conexión regionales, consulte Nombres de subdominios personalizados para Cognitive Services.
En la ventana siguiente, copie el valor de KEY 1 en el Portapapeles.
Adición de credenciales de Computer Vision
A continuación, agregará las credenciales necesarias a la aplicación para que pueda acceder a los recursos de Computer Vision.
Vaya al archivo Web.config en la raíz del proyecto. Agregue las siguientes instrucciones a la sección <appSettings>
del archivo, pero reemplace VISION_KEY
por la clave que copió en el paso anterior y VISION_ENDPOINT
por la dirección URL que guardó en el paso anterior.
<add key="SubscriptionKey" value="VISION_KEY" />
<add key="VisionEndpoint" value="VISION_ENDPOINT" />
Luego, en el Explorador de soluciones, haga clic con el botón derecho en el proyecto y use el comando Administrar paquetes NuGet para instalar el paquete Microsoft.Azure.CognitiveServices.Vision.ComputerVision. Dicho paquete contiene los tipos necesarios para llamar a Computer Vision API.
Incorporación del código de generación de metadatos
A continuación, agregará el código que realmente usa el servicio Computer Vision para crear metadatos para las imágenes.
Abra el archivo HomeController.cs, que encontrará en la carpeta Controllers del proyecto, y agregue las siguientes
using
instrucciones al principio del mismo:using Microsoft.Azure.CognitiveServices.Vision.ComputerVision; using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
A continuación, vaya al método Upload; este método convierte y carga imágenes en Blob Storage. Agregue el código siguiente inmediatamente después del bloque que comienza por
// Generate a thumbnail
(o al final del proceso de creación de blobs de imágenes). Este código toma el blob que contiene la imagen (photo
) y utiliza Computer Vision para generar una descripción de ella. Computer Vision API también genera una lista de palabras clave que se aplican a la imagen. Tanto la descripción como las palabras clave generadas se almacenan en los metadatos del blob para que se pueden recuperar más adelante.// Submit the image to the Azure Computer Vision API ComputerVisionClient vision = new ComputerVisionClient( new ApiKeyServiceClientCredentials(ConfigurationManager.AppSettings["SubscriptionKey"]), new System.Net.Http.DelegatingHandler[] { }); vision.Endpoint = ConfigurationManager.AppSettings["VisionEndpoint"]; List<VisualFeatureTypes?> features = new List<VisualFeatureTypes?>() { VisualFeatureTypes.Description }; var result = await vision.AnalyzeImageAsync(photo.Uri.ToString(), features); // Record the image description and tags in blob metadata photo.Metadata.Add("Caption", result.Description.Captions[0].Text); for (int i = 0; i < result.Description.Tags.Count; i++) { string key = String.Format("Tag{0}", i); photo.Metadata.Add(key, result.Description.Tags[i]); } await photo.SetMetadataAsync();
A continuación, vaya al método Index en el mismo archivo. Este método enumera los blobs de imágenes almacenados en el contenedor de blobs de destino (como instancias de IListBlobItem) y los pasa a la vista de aplicación. Reemplace el bloque
foreach
de este método por el siguiente código. Este código llama a CloudBlockBlob.FetchAttributes para obtener los metadatos adjuntos de cada blob. Extrae la descripción generada por el equipo (caption
) de los metadatos y la agrega al objeto BlobInfo, que se pasa a la 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 }); } }
Prueba de la aplicación
Guarde los cambios en Visual Studio y presione Ctrl+F5 para iniciar la aplicación en el explorador. Use la aplicación para cargar algunas imágenes más, ya sea desde el conjunto de fotos que descargó o desde su propia carpeta. Cuando mueva el puntero sobre una de las nuevas imágenes de la vista, debería aparecer una ventana de información sobre herramientas y mostrar el título de la imagen generado automáticamente.
Para ver todos los metadatos adjuntos, use el Explorador de Azure Storage para ver el contenedor de almacenamiento que usa para las imágenes. Haga clic con el botón derecho en cualquiera de los blobs del mismo y seleccione Propiedades. En el cuadro de diálogo, verá una lista de pares clave-valor. La descripción de la imagen generada automáticamente se almacena en el elemento Caption
y las palabras clave de búsqueda se almacenan en Tag0
, Tag1
, etc. Cuando haya terminado, haga clic en Cancelar para cerrar el cuadro de diálogo.
Adición de un cuadro de búsqueda a la aplicación
En esta sección, agregará un cuadro de búsqueda a la página principal, lo que permite a los usuarios realizar búsquedas de palabras clave en las imágenes que han cargado. Las palabras clave son las que genera Computer Vision API y se almacenan en los metadatos de los blobs.
Abra el archivo Index.cshtml en la carpeta Views/Home del proyecto y agregue las siguientes instrucciones al elemento
<div>
vacío con el atributoclass="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> }
Este código y marcado agregan un cuadro de búsqueda y un botón Search (Buscar) a la página principal.
Abra el archivo HomeController.cs, que encontrará en la carpeta Controllers (Controladores) del proyecto, y agregue el siguiente método a la clase HomeController:
[HttpPost] public ActionResult Search(string term) { return RedirectToAction("Index", new { id = term }); }
Este es el método al que se llama cuando el usuario hace clic en el botón Search (Buscar) agregado en el paso anterior. Actualiza la página e incluye un parámetro de búsqueda en la dirección URL.
Reemplace el método Index por la siguiente implementación:
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 el método Index ahora acepta el parámetro id, que contiene el valor que el usuario ha especificado en el cuadro de búsqueda. Un parámetro id vacío o que falta indica que se deben mostrar todas las fotos.
Agregue el método auxiliar siguiente a la clase 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; }
El método Index llama a este método para determinar si las palabras clave de metadatos asociadas a un blob de imagen determinado contienen el término de búsqueda especificado por el usuario.
Vuelva a iniciar la aplicación y cargue varias fotos. No dude en usar sus propias fotos, no solo las que se proporcionan con el tutorial.
Escriba una palabra clave como "river" (río) en el cuadro de búsqueda. A continuación, haga clic en el botón Search (Buscar).
Los resultados de la búsqueda variarán en función de lo que haya especificado y de las imágenes que haya cargado. Sin embargo, el resultado debe ser una lista filtrada de imágenes cuyas palabras clave de metadatos incluyan todo o parte de la palabra clave que ha especificado.
Haga clic en el botón Atrás del explorador para volver a mostrar todas las imágenes.
Casi hemos acabado. Es el momento de implementar la aplicación en la nube.
Implementar la aplicación en Azure
En esta sección, implementará la aplicación en Azure desde Visual Studio. Permitirá que Visual Studio cree una aplicación web de Azure automáticamente, lo que le evitará tener que ir a Azure Portal y crearla por separado.
Haga clic con el botón derecho en el proyecto en el Explorador de soluciones y seleccione Publicar... en el menú contextual. Asegúrese de que Microsoft Azure App Service y Crear nuevo estén seleccionados y, a continuación, haga clic en el botón Publicar.
En el siguiente cuadro de diálogo, seleccione el grupo de recursos "IntellipixResources" en Grupo de recursos. Haga clic en el botón Nuevo... situado junto a "Plan de App Service" y cree un nuevo plan de App Service en la misma ubicación que seleccionó para la cuenta de almacenamiento en Crear una cuenta de almacenamiento, aceptando los valores predeterminados en cualquier otro campo. Para finalizar, haga clic en el botón Crear.
Transcurridos unos instantes, la aplicación aparecerá en una ventana del explorador. Observe la dirección URL en la barra de direcciones. La aplicación ya no se ejecuta localmente; está en la Web, donde es accesible públicamente.
Si realiza cambios en la aplicación y desea insertar los cambios en la Web, vuelva a realizar el proceso de publicación. Todavía puede probar los cambios localmente antes de publicar en la Web.
Limpieza de recursos
Si desea seguir trabajando en la aplicación web, consulte la sección Pasos siguientes. Si no planea seguir usando esta aplicación, debe eliminar todos los recursos específicos de la misma. Para ello, puede eliminar el grupo de recursos que contiene la suscripción de Azure Storage y el recurso de Computer Vision. De esta forma se quita la cuenta de almacenamiento, los blobs que se han cargado en ella y el recurso de App Service necesario para conectarse con la aplicación web ASP.NET.
Para eliminar el grupo de recursos, abra la pestaña Grupos de recursos del portal, vaya al grupo de recursos que usó para el proyecto y haga clic en Eliminar grupo de recursos en la parte superior de la vista. Se le pedirá que escriba el nombre del grupo de recursos para confirmar que desea eliminarlo. Una vez eliminado, no se puede recuperar un grupo de recursos.
Pasos siguientes
Hay mucho más que puede hacer para usar Azure y desarrollar aún más la aplicación Intellipix. Por ejemplo, podría agregar compatibilidad para autenticar a los usuarios, eliminar fotos y, en lugar de obligar al usuario a esperar a que Cognitive Services procese una foto después de una carga, podría usar Azure Functions para llamar a Computer Vision API de forma asincrónica cada vez que se agrega una imagen al almacenamiento de blobs. También puede realizar cualquier otra operación de análisis de imágenes sobre la imagen, como se describe en la introducción.