Início Rápido: Obtenha insights de imagem usando a API REST da Pesquisa Visual do Bing e o C#
Aviso
Em 30 de outubro de 2020, as APIs de Pesquisa do Bing foram migradas dos serviços de IA do Azure para os Serviços de Pesquisa do Bing. Esta documentação é fornecida apenas para referência. Para obter a documentação atualizada, consulte a documentação da API de pesquisa do Bing. Para obter instruções sobre como criar novos recursos do Azure para a Pesquisa do Bing, consulte Criar um recurso de Pesquisa do Bing por meio do Azure Marketplace.
Este início rápido demonstra como fazer upload de uma imagem para a API da Pesquisa Visual do Bing e para exibir os insights retornados.
Pré-requisitos
- Qualquer edição do Visual Studio 2019.
- A estrutura Json.NET, disponível como um pacote NuGet.
- Se você estiver usando Linux/MacOS, poderá executar usando o Mono.
Criar um recurso do Azure
Comece a usar a API da Pesquisa Visual do Bing criando um dos seguintes recursos do Azure:
Recurso de Pesquisa do Bing v7
- Disponível por meio do portal do Azure até que você exclua o recurso.
- Selecione o tipo de preço
S9
.
- Disponível por meio do portal do Azure até que você exclua o recurso.
- Use a mesma chave e ponto de extremidade para seus aplicativos nos vários serviços de IA do Azure.
Criar e inicializar um projeto
No Visual Studio, crie uma solução de console chamada BingSearchApisQuickStart. Adicione os seguintes namespaces ao arquivo de código principal:
using System; using System.Text; using System.Net; using System.IO; using System.Collections.Generic;
Adicione variáveis para sua chave de assinatura, ponto de extremidade e o caminho para a imagem que você deseja carregar. Para o valor
uriBase
, você pode usar o ponto de extremidade global no código a seguir ou usar o ponto de extremidade do subdomínio personalizado exibido no portal do Azure para seu 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>";
Crie um método chamado
GetImageFileName()
para obter o caminho da sua imagem.static string GetImageFileName(string path) { return new FileInfo(path).Name; }
Crie um método para obter os dados binários da imagem.
static byte[] GetImageBinary(string path) { return File.ReadAllBytes(path); }
Criar os dados de formulário
Para fazer upload de uma imagem local, crie primeiro os dados do formulário a serem enviados à API. Os dados do formulário incluem o cabeçalho
Content-Disposition
, o parâmetroname
definido como "image" e o parâmetrofilename
definido como o nome do arquivo da imagem. O conteúdo do formulário contém os dados binários da imagem. O tamanho máximo da imagem que pode ser carregada é 1 MB.--boundary_1234-abcd Content-Disposition: form-data; name="image"; filename="myimagefile.jpg" ÿØÿà JFIF ÖÆ68g-¤CWŸþ29ÌÄøÖ‘º«™æ±èuZiÀ)"óÓß°Î= ØJ9á+*G¦... --boundary_1234-abcd--
Adicione cadeias de caracteres de limite para formatar os dados de formulário de POST. As cadeias de caracteres de limite determinam os caracteres de início, término e de nova linha para os dados.
// 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 as seguintes variáveis para adicionar parâmetros aos dados do formulário:
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;
Crie uma função chamada
BuildFormDataStart()
para criar o início dos dados de formulário usando as cadeias de caracteres de limite e o caminho da imagem.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; }
Crie uma função chamada
BuildFormDataEnd()
para criar o término dos dados de formulário usando as cadeias de caracteres de limite e o caminho da imagem.static string BuildFormDataEnd(string boundary) { return CRLF + CRLF + string.Format(EndBoundaryTemplate, boundary) + CRLF; }
Chame a API da Pesquisa Visual do Bing
Crie uma função para chamar o ponto de extremidade da Pesquisa Visual do Bing e retornar a resposta JSON. A função usa o início e o término dos dados de formulário, uma matriz de bytes que contém os dados de imagem e um valor
contentType
.Use um
WebRequest
para armazenar seu URI, o valor contentType e cabeçalhos.Use
request.GetRequestStream()
para gravar os dados de formulário e de imagem; em seguida, obtenha a resposta. Sua função deve ser semelhante ao seguinte 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; }
Criar o Método principal
No método
Main()
do seu aplicativo, obtenha o nome do arquivo e os dados binários da sua imagem.var filename = GetImageFileName(imagePath); var imageBinary = GetImageBinary(imagePath);
Configure o corpo do POST formatando o limite dele. Em seguida, chame
BuildFormDataStart()
eBuildFormDataEnd()
para criar os dados do formulário.// Set up POST body. var boundary = string.Format(BoundaryTemplate, Guid.NewGuid()); var startFormData = BuildFormDataStart(boundary, filename); var endFormData = BuildFormDataEnd(boundary);
Crie o valor
ContentType
formatandoCONTENT_TYPE_HEADER_PARAMS
e o limite dos dados de formulário.var contentTypeHdrValue = string.Format(CONTENT_TYPE_HEADER_PARAMS, boundary);
Obtenha a resposta da API chamando
BingImageSearch()
e imprima a resposta.var json = BingImageSearch(startFormData, endFormData, imageBinary, contentTypeHdrValue); Console.WriteLine(json); Console.WriteLine("enter any key to continue"); Console.readKey();
Usando HttpClient
Se você usar HttpClient
, poderá usar a classe MultipartFormDataContent
para criar os dados de formulário. Use as seguintes seções de código para substituir os métodos correspondentes no exemplo anterior:
Substitua o método
Main()
pelo seguinte código: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); } }
Substitua o método
BingImageSearch()
pelo seguinte código:/// <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; }