Szybki start: uzyskiwanie szczegółowych informacji o obrazach przy użyciu interfejsu API REST wyszukiwania wizualnego Bing i języka C#
Ostrzeżenie
30 października 2020 r. interfejsy API Wyszukiwanie Bing zostały przeniesione z usług Azure AI do usług Wyszukiwanie Bing Services. Ta dokumentacja jest udostępniana tylko do celów referencyjnych. Aby uzyskać zaktualizowaną dokumentację, zobacz dokumentację interfejsu API wyszukiwania Bing. Aby uzyskać instrukcje dotyczące tworzenia nowych zasobów platformy Azure na potrzeby wyszukiwania Bing, zobacz Tworzenie zasobu Wyszukiwanie Bing za pośrednictwem Azure Marketplace.
W tym przewodniku Szybki start pokazano, jak przekazać obraz do interfejsu API wyszukiwania wizualnego Bing i wyświetlić zwrócone szczegółowe informacje.
Wymagania wstępne
- Dowolna wersja programu Visual Studio 2019.
- Struktura Json.NET dostępna jako pakiet NuGet.
- Jeśli używasz systemu Linux/MacOS, możesz uruchomić tę aplikację przy użyciu platformy Mono.
Tworzenie zasobu platformy Azure
Zacznij korzystać z interfejsu API wyszukiwania wizualnego Bing, tworząc jeden z następujących zasobów platformy Azure:
zasób Wyszukiwanie Bing w wersji 7
- Dostępne za pośrednictwem Azure Portal do momentu usunięcia zasobu.
- Wybierz warstwę cenową
S9
.
- Dostępne za pośrednictwem Azure Portal do momentu usunięcia zasobu.
- Użyj tego samego klucza i punktu końcowego dla aplikacji w wielu usługach azure AI.
Tworzenie i inicjowanie projektu
W programie Visual Studio utwórz nowe rozwiązanie konsoli o nazwie BingSearchApisQuickStart. Dodaj następujące przestrzenie nazw do głównego pliku kodu:
using System; using System.Text; using System.Net; using System.IO; using System.Collections.Generic;
Dodaj zmienne dla klucza subskrypcji, punktu końcowego i ścieżki do obrazu, który chcesz przekazać.
uriBase
Dla wartości można użyć globalnego punktu końcowego w poniższym kodzie lub użyć niestandardowego punktu końcowego poddomeny wyświetlanego w Azure Portal dla zasobu.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>";
Utwórz metodę o nazwie
GetImageFileName()
, aby uzyskać ścieżkę dla obrazu.static string GetImageFileName(string path) { return new FileInfo(path).Name; }
Utwórz metodę , aby pobrać dane binarne obrazu.
static byte[] GetImageBinary(string path) { return File.ReadAllBytes(path); }
Tworzenie danych formularza
Aby przekazać obraz lokalny, najpierw skompiluj dane formularza do wysłania do interfejsu API. Dane formularza zawierają
Content-Disposition
nagłówek,name
parametr ustawiony na wartość "image" ifilename
parametr ustawiony na nazwę pliku obrazu. Zawartość formularza zawiera dane binarne obrazu. Maksymalny rozmiar obrazu, który można przekazać, wynosi 1 MB.--boundary_1234-abcd Content-Disposition: form-data; name="image"; filename="myimagefile.jpg" ÿØÿà JFIF ÖÆ68g-¤CWŸþ29ÌÄøÖ‘º«™æ±èuZiÀ)"óÓß°Î= ØJ9á+*G¦... --boundary_1234-abcd--
Dodaj ciągi granic, aby sformatować dane formularza POST. Ciągi granic określają znaki początkowe, końcowe i nowe wiersze dla danych.
// 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}--";
Użyj następujących zmiennych, aby dodać parametry do danych formularza:
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;
Utwórz funkcję o nazwie
BuildFormDataStart()
, aby utworzyć początek danych formularza przy użyciu ciągów granic i ścieżki obrazu.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; }
Utwórz funkcję o nazwie
BuildFormDataEnd()
, aby utworzyć koniec danych formularza przy użyciu ciągów granic.static string BuildFormDataEnd(string boundary) { return CRLF + CRLF + string.Format(EndBoundaryTemplate, boundary) + CRLF; }
Wywoływanie interfejsu API wyszukiwania wizualnego Bing
Utwórz funkcję w celu wywołania punktu końcowego wyszukiwania wizualnego Bing i zwrócenia odpowiedzi JSON. Funkcja przyjmuje początek i koniec danych formularza, tablicę bajtów zawierającą
contentType
dane obrazu i wartość.Użyj żądania
WebRequest
do przechowywania identyfikatora URI, wartości contentType i nagłówków.Użyj
request.GetRequestStream()
polecenia , aby zapisać dane formularza i obrazu, a następnie uzyskać odpowiedź. Funkcja powinna być podobna do następującego kodu: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; }
Tworzenie metody Main
W metodzie
Main()
aplikacji pobierz nazwę pliku i dane binarne obrazu.var filename = GetImageFileName(imagePath); var imageBinary = GetImageBinary(imagePath);
Skonfiguruj treść POST, formatując jej granicę. Następnie wywołaj metodę
BuildFormDataStart()
iBuildFormDataEnd()
, aby utworzyć dane formularza.// Set up POST body. var boundary = string.Format(BoundaryTemplate, Guid.NewGuid()); var startFormData = BuildFormDataStart(boundary, filename); var endFormData = BuildFormDataEnd(boundary);
Utwórz wartość,
ContentType
formatującCONTENT_TYPE_HEADER_PARAMS
i granicę danych formularza.var contentTypeHdrValue = string.Format(CONTENT_TYPE_HEADER_PARAMS, boundary);
Pobierz odpowiedź interfejsu API, wywołując
BingImageSearch()
metodę , a następnie wyświetl odpowiedź.var json = BingImageSearch(startFormData, endFormData, imageBinary, contentTypeHdrValue); Console.WriteLine(json); Console.WriteLine("enter any key to continue"); Console.readKey();
Korzystanie z obiektu HttpClient
Jeśli używasz klasy HttpClient
, możesz użyć MultipartFormDataContent
klasy do skompilowania danych formularza. Użyj poniższych sekcji kodu, aby zastąpić odpowiednie metody w poprzednim przykładzie:
Zastąp metodę
Main()
poniższym kodem: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); } }
Zastąp metodę
BingImageSearch()
poniższym kodem:/// <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; }