Краткое руководство. Получение аналитических сведений об изображениях с помощью REST API визуального поиска Bing и C#
Предупреждение
30 октября 2020 г. API-интерфейсы Поиск Bing перемещены из служб ИИ Azure в службы Поиск Bing. Эта документация приводится только для справки. Обновленную информацию см. в документации по API Поиска Bing. Инструкции по созданию ресурсов Azure для Поиска Bing см. в статье о том, как создать ресурс для Поиска Bing с помощью Azure Marketplace.
В этом кратком руководстве показано, как отправлять изображение в API Визуального поиска Bing и просматривать возвращаемые им аналитические сведения.
Предварительные требования
- Любой выпуск Visual Studio 2019.
- Платформа Json.NET, доступная в виде пакета NuGet.
- Если вы используете Linux или MacOS, это приложение можно запустить с помощью Mono.
Создание ресурса Azure
Чтобы начать работу с API Визуального поиска Bing, создайте один из следующих ресурсов Azure.
- доступен на портале Azure до удаления.
- Выберите ценовую категорию
S9
.
- доступен на портале Azure до удаления.
- Используйте один и тот же ключ и конечную точку для приложений в нескольких службах ИИ Azure.
Создание и инициализация проекта
В Visual Studio создайте консольное решение с именем BingSearchApisQuickStart. Добавьте следующие пространства имен в основной файл кода:
using System; using System.Text; using System.Net; using System.IO; using System.Collections.Generic;
Добавьте переменные для ключа подписки, конечной точки и пути к изображению, которое нужно отправить. Для значения
uriBase
вы можете использовать глобальную конечную точку, указанную в коде ниже, или конечную точку личного поддомена, которая отображается на портале Azure для вашего ресурса.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>";
Создайте метод с именем
GetImageFileName()
, чтобы получить путь для изображения.static string GetImageFileName(string path) { return new FileInfo(path).Name; }
Создайте метод, чтобы получить двоичные данные изображения.
static byte[] GetImageBinary(string path) { return File.ReadAllBytes(path); }
Создание данных формы
Чтобы отправить локальное изображение, сначала создайте данные формы для отправки в API. Данные формы содержат заголовок
Content-Disposition
, для параметраname
задано значение "Image", а для параметраfilename
задано имя файла изображения. Форма содержит двоичные данные изображения. Максимально допустимый размер отправляемого изображения — 1 МБ.--boundary_1234-abcd Content-Disposition: form-data; name="image"; filename="myimagefile.jpg" ÿØÿà JFIF ÖÆ68g-¤CWŸþ29ÌÄøÖ‘º«™æ±èuZiÀ)"óÓß°Î= ØJ9á+*G¦... --boundary_1234-abcd--
Добавьте строки границ для форматирования данных формы POST. Строки границ определяют в данных символы начала, окончания и новой строки.
// 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}--";
Используйте следующие переменные для добавления параметров к данным формы:
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;
Создайте функцию с именем
BuildFormDataStart()
, чтобы определить начало данных формы, используя строки границ и путь к изображению.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; }
Создайте функцию с именем
BuildFormDataEnd()
, чтобы определить конец данных формы, используя строки границ.static string BuildFormDataEnd(string boundary) { return CRLF + CRLF + string.Format(EndBoundaryTemplate, boundary) + CRLF; }
Вызов API визуального поиска Bing
Создайте функцию, чтобы вызвать конечную точку Визуального поиска Bing и вернуть ответ в формате JSON. Функция принимает начало и конец формы данных, массив байтов с данными изображения и значение
contentType
.Используйте
WebRequest
для хранения универсального кода ресурса, значения contentType и заголовков.Используйте
request.GetRequestStream()
для записи формы и данных изображения и получения ответа. Функция должна содержать примерно такой код: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; }
Создание метода Main
В методе
Main()
приложения получите имя файла и двоичные данные изображения.var filename = GetImageFileName(imagePath); var imageBinary = GetImageBinary(imagePath);
Настройте текст запроса POST, отформатировав его границу. Затем вызовите
BuildFormDataStart()
иBuildFormDataEnd()
, чтобы создать данные формы.// Set up POST body. var boundary = string.Format(BoundaryTemplate, Guid.NewGuid()); var startFormData = BuildFormDataStart(boundary, filename); var endFormData = BuildFormDataEnd(boundary);
Создайте значение
ContentType
, отформатировавCONTENT_TYPE_HEADER_PARAMS
и границы данных формы.var contentTypeHdrValue = string.Format(CONTENT_TYPE_HEADER_PARAMS, boundary);
Получите ответ API, вызвав
BingImageSearch()
, и выведите ответ:var json = BingImageSearch(startFormData, endFormData, imageBinary, contentTypeHdrValue); Console.WriteLine(json); Console.WriteLine("enter any key to continue"); Console.readKey();
Использование HttpClient
Если вы используете HttpClient
, можно использовать класс MultipartFormDataContent
для создания данных формы. Используйте следующие секции кода для замены соответствующих методов в предыдущем примере.
Замените метод
Main()
следующим кодом: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); } }
Замените метод
BingImageSearch()
следующим кодом:/// <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; }
Дальнейшие действия
Create a Visual Search single-page web app (Создание одностраничного веб-приложения Визуального поиска)