Inicio rápido: Obtención de conclusiones de imágenes mediante la API de REST Bing Visual Search y C#
Advertencia
El 30 de octubre de 2020, las API de Bing Search se trasladaron de los servicios de Azure AI a los servicios de Bing Search. Esta documentación se proporciona solo como referencia. Para obtener documentación actualizada, consulte la documentación de Bing Search API. Para obtener instrucciones sobre cómo crear nuevos recursos de Azure para Bing Search, consulte el artículo sobre la creación de un recurso de Bing Search a través de Azure Marketplace.
Este inicio rápido muestra cómo cargar una imagen en la API Bing Visual Search y cómo ver la información detallada que devuelve.
Requisitos previos
- Cualquier edición de Visual Studio 2019.
- La plataforma Json.NET, disponible como paquete NuGet.
- Si usa Linux o MacOS, puede ejecutar esta aplicación con Mono.
Creación de un recurso de Azure
Comience a usar la API Bing Visual Search mediante la creación de uno de los recursos de Azure que se indican a continuación:
- Disponible en Azure Portal hasta que lo elimine.
- Seleccione el plan de tarifa
S9
.
- Disponible en Azure Portal hasta que lo elimine.
- Utilice la misma clave y el mismo punto de conexión para sus aplicaciones en varios servicios de Azure AI.
Creación e inicialización de un proyecto
En Visual Studio, cree una solución de consola denominada BingSearchApisQuickStart. Agregue los siguientes espacios de nombres al archivo de código principal:
using System; using System.Text; using System.Net; using System.IO; using System.Collections.Generic;
Agregue variables para la clave de suscripción, el punto de conexión y la ruta de acceso a la imagen que quiere cargar. Para el valor
uriBase
puede usar el punto de conexión global en el código siguiente, o el punto de conexión del subdominio personalizado que se muestra en Azure Portal para el recurso.const string accessKey = "<my_subscription_key>"; const string uriBase = "https://api.cognitive.microsoft.com/bing/v7.0/images/visualsearch"; static string imagePath = @"<path_to_image>";
Cree un método llamado
GetImageFileName()
para obtener la ruta de acceso a la imagen.static string GetImageFileName(string path) { return new FileInfo(path).Name; }
Cree un método para obtener los datos binarios de la imagen.
static byte[] GetImageBinary(string path) { return File.ReadAllBytes(path); }
Creación de los datos del formulario
Para cargar una imagen local, cree primero los datos del formulario que se van a enviar a la API. Los datos del formulario incluyen el encabezado
Content-Disposition
, el parámetroname
establecido en "image" y el parámetrofilename
establecido en el nombre de archivo de la imagen. El contenido del formulario incluye los datos binarios de la imagen. El tamaño de imagen máximo que puede cargar es de 1 MB.--boundary_1234-abcd Content-Disposition: form-data; name="image"; filename="myimagefile.jpg" ÿØÿà JFIF ÖÆ68g-¤CWŸþ29ÌÄøÖ‘º«™æ±èuZiÀ)"óÓß°Î= ØJ9á+*G¦... --boundary_1234-abcd--
Agregue cadenas de límite para dar formato a los datos del formulario POST. Las cadenas de límite determinan los caracteres de inicio, final y caracteres de nueva línea de los datos.
// Boundary strings for form data in body of POST. const string CRLF = "\r\n"; static string BoundaryTemplate = "batch_{0}"; static string StartBoundaryTemplate = "--{0}"; static string EndBoundaryTemplate = "--{0}--";
Use las variables siguientes para agregar parámetros a los datos del formulario:
const string CONTENT_TYPE_HEADER_PARAMS = "multipart/form-data; boundary={0}"; const string POST_BODY_DISPOSITION_HEADER = "Content-Disposition: form-data; name=\"image\"; filename=\"{0}\"" + CRLF +CRLF;
Genere una función llamada
BuildFormDataStart()
para crear el inicio de los datos del formulario mediante las cadenas de límite y la ruta de acceso de la imagen.static string BuildFormDataStart(string boundary, string filename) { var startBoundary = string.Format(StartBoundaryTemplate, boundary); var requestBody = startBoundary + CRLF; requestBody += string.Format(POST_BODY_DISPOSITION_HEADER, filename); return requestBody; }
Genere una función llamada
BuildFormDataEnd()
para crear el final de los datos del formulario mediante las cadenas de límite.static string BuildFormDataEnd(string boundary) { return CRLF + CRLF + string.Format(EndBoundaryTemplate, boundary) + CRLF; }
Llamada a Bing Visual Search API
Cree una función para llamar al punto de conexión de Bing Visual Search y devolver la respuesta JSON. La función toma el inicio y el final de los datos del formulario, una matriz de bytes que contiene los datos de imagen y un valor
contentType
.Use
WebRequest
para almacenar el identificador URI, el valor contentType y los encabezados.Use
request.GetRequestStream()
para escribir los datos del formulario y de la imagen y, a continuación, obtener la respuesta. La función debe ser parecida al siguiente código:static string BingImageSearch(string startFormData, string endFormData, byte[] image, string contentTypeValue) { WebRequest request = HttpWebRequest.Create(uriBase); request.ContentType = contentTypeValue; request.Headers["Ocp-Apim-Subscription-Key"] = accessKey; request.Method = "POST"; // Writes the boundary and Content-Disposition header, then writes // the image binary, and finishes by writing the closing boundary. using (Stream requestStream = request.GetRequestStream()) { StreamWriter writer = new StreamWriter(requestStream); writer.Write(startFormData); writer.Flush(); requestStream.Write(image, 0, image.Length); writer.Write(endFormData); writer.Flush(); writer.Close(); } HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result; string json = new StreamReader(response.GetResponseStream()).ReadToEnd(); return json; }
Creación del método principal
En el método
Main()
de la aplicación, obtenga el nombre del archivo y los datos binarios de la imagen.var filename = GetImageFileName(imagePath); var imageBinary = GetImageBinary(imagePath);
Configure el cuerpo POST dando formato a su límite. A continuación, llame a
BuildFormDataStart()
yBuildFormDataEnd()
para crear los datos del formulario.// Set up POST body. var boundary = string.Format(BoundaryTemplate, Guid.NewGuid()); var startFormData = BuildFormDataStart(boundary, filename); var endFormData = BuildFormDataEnd(boundary);
Cree el valor
ContentType
dando formato aCONTENT_TYPE_HEADER_PARAMS
y al límite de los datos del formulario.var contentTypeHdrValue = string.Format(CONTENT_TYPE_HEADER_PARAMS, boundary);
Obtenga la respuesta de API mediante una llamada a
BingImageSearch()
e imprima la respuesta.var json = BingImageSearch(startFormData, endFormData, imageBinary, contentTypeHdrValue); Console.WriteLine(json); Console.WriteLine("enter any key to continue"); Console.readKey();
Usar HttpClient
Si usa HttpClient
, puede emplear la clase MultipartFormDataContent
para generar los datos del formulario. Puede usar las siguientes secciones de código para reemplazar los métodos correspondientes en el ejemplo anterior:
Reemplace el método
Main()
por el código siguiente:static void Main() { try { Console.OutputEncoding = System.Text.Encoding.UTF8; if (accessKey.Length == 32) { if (IsImagePathSet(imagePath)) { var filename = GetImageFileName(imagePath); Console.WriteLine("Getting image insights for image: " + filename); var imageBinary = GetImageBinary(imagePath); var boundary = string.Format(BoundaryTemplate, Guid.NewGuid()); var json = BingImageSearch(imageBinary, boundary, uriBase, accessKey); Console.WriteLine("\nJSON Response:\n"); Console.WriteLine(JsonPrettyPrint(json)); } } else { Console.WriteLine("Invalid Bing Visual Search API subscription key!"); Console.WriteLine("Please paste yours into the source code."); } Console.Write("\nPress Enter to exit "); Console.ReadLine(); } catch (Exception e) { Console.WriteLine(e.Message); } }
Reemplace el método
BingImageSearch()
por el código siguiente:/// <summary> /// Calls the Bing visual search endpoint and returns the JSON response. /// </summary> static string BingImageSearch(byte[] image, string boundary, string uri, string subscriptionKey) { var requestMessage = new HttpRequestMessage(HttpMethod.Post, uri); requestMessage.Headers.Add("Ocp-Apim-Subscription-Key", accessKey); var content = new MultipartFormDataContent(boundary); content.Add(new ByteArrayContent(image), "image", "myimage"); requestMessage.Content = content; var httpClient = new HttpClient(); Task<HttpResponseMessage> httpRequest = httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, CancellationToken.None); HttpResponseMessage httpResponse = httpRequest.Result; HttpStatusCode statusCode = httpResponse.StatusCode; HttpContent responseContent = httpResponse.Content; string json = null; if (responseContent != null) { Task<String> stringContentsTask = responseContent.ReadAsStringAsync(); json = stringContentsTask.Result; } return json; }