Skip to content

Commit b32b155

Browse files
authored
Updated structure
1 parent c0aadc0 commit b32b155

File tree

1 file changed

+54
-208
lines changed

1 file changed

+54
-208
lines changed
Lines changed: 54 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1+
using Newtonsoft.Json;
12
using System;
23
using System.Text;
34
using System.Net;
45
using System.IO;
5-
using System.Collections.Generic;
66

7-
namespace VisualSearchUpload
8-
{
7+
/* This sample makes a call to the Bing Visual Search API with a query image and returns similar images with details.
8+
* Bing Visual Search API:
9+
* https://docs.microsoft.com/en-us/rest/api/cognitiveservices/bingvisualsearch/images/visualsearch
10+
*/
911

12+
namespace BingVisualSearch
13+
{
1014
class Program
1115
{
12-
// **********************************************
13-
// *** Update and verify the following values. ***
14-
// **********************************************
15-
16-
// Add your Azure Bing Search V7 subscription key to your environment variables.
17-
const string accessKey = Environment.GetEnvironmentVariable("BING_SEARCH_V7_SUBSCRIPTION_KEY");
18-
// Add your Azure Bing Search V7 endpoint to your environment variables.
19-
const string uriBase = Environment.GetEnvironmentVariable("BING_SEARCH_V7_ENDPOINT") + "/bing/v7.0/images/visualsearch";
16+
// Add your Azure Bing Search V7 subscription key and endpoint to your environment variables.
17+
static string subscriptionKey = Environment.GetEnvironmentVariable("BING_SEARCH_V7_SUBSCRIPTION_KEY");
18+
static string endpoint = Environment.GetEnvironmentVariable("BING_SEARCH_V7_ENDPOINT") + "/bing/v7.0/images/visualsearch";
2019

2120
// Set the path to the image that you want to get insights of.
22-
static string imagePath = @"<pathtoimagegoeshere>";
21+
static string imagePath = @"objects.jpg";
2322

2423
// Boundary strings for form data in body of POST.
2524
const string CRLF = "\r\n";
@@ -28,216 +27,63 @@ class Program
2827
static string EndBoundaryTemplate = "--{0}--";
2928

3029
const string CONTENT_TYPE_HEADER_PARAMS = "multipart/form-data; boundary={0}";
31-
const string POST_BODY_DISPOSITION_HEADER = "Content-Disposition: form-data; name=\"image\"; filename=\"{0}\"" + CRLF +CRLF;
30+
const string POST_BODY_DISPOSITION_HEADER = "Content-Disposition: form-data; name=\"image\"; filename=\"{0}\"" + CRLF + CRLF;
3231

3332

3433
static void Main()
3534
{
3635
try
3736
{
38-
Console.OutputEncoding = System.Text.Encoding.UTF8;
39-
40-
if (accessKey.Length == 32)
41-
{
42-
if (IsImagePathSet(imagePath))
43-
{
44-
var filename = GetImageFileName(imagePath);
45-
Console.WriteLine("Getting image insights for image: " + filename);
46-
var imageBinary = GetImageBinary(imagePath);
47-
48-
// Set up POST body.
49-
var boundary = string.Format(BoundaryTemplate, Guid.NewGuid());
50-
var startFormData = BuildFormDataStart(boundary, filename);
51-
var endFormData = BuildFormDataEnd(boundary);
52-
var contentTypeHdrValue = string.Format(CONTENT_TYPE_HEADER_PARAMS, boundary);
53-
54-
var json = BingImageSearch(startFormData, endFormData, imageBinary, contentTypeHdrValue);
55-
56-
Console.WriteLine("\nJSON Response:\n");
57-
Console.WriteLine(JsonPrettyPrint(json));
58-
}
59-
}
60-
else
37+
Console.OutputEncoding = Encoding.UTF8;
38+
39+
// Gets image.
40+
var filename = new FileInfo(imagePath).FullName;
41+
Console.WriteLine("Getting image insights for image: " + Path.GetFileName(filename));
42+
var imageBinary = File.ReadAllBytes(imagePath);
43+
44+
// Sets up POST body.
45+
var boundary = string.Format(BoundaryTemplate, Guid.NewGuid());
46+
47+
// Builds form start data.
48+
var startBoundary = string.Format(StartBoundaryTemplate, boundary);
49+
var startFormData = startBoundary + CRLF;
50+
startFormData += string.Format(POST_BODY_DISPOSITION_HEADER, filename);
51+
52+
// Builds form end data.
53+
var endFormData = CRLF + CRLF + string.Format(EndBoundaryTemplate, boundary) + CRLF;
54+
var contentTypeHeaderValue = string.Format(CONTENT_TYPE_HEADER_PARAMS, boundary);
55+
56+
// Sets up the request for a visual search.
57+
WebRequest request = HttpWebRequest.Create(endpoint);
58+
request.ContentType = contentTypeHeaderValue;
59+
request.Headers["Ocp-Apim-Subscription-Key"] = subscriptionKey;
60+
request.Method = "POST";
61+
62+
// Writes the boundary and Content-Disposition header, then writes
63+
// the image binary, and finishes by writing the closing boundary.
64+
using (Stream requestStream = request.GetRequestStream())
6165
{
62-
Console.WriteLine("Invalid Bing Visual Search API subscription key!");
63-
Console.WriteLine("Please paste yours into the source code.");
66+
StreamWriter writer = new StreamWriter(requestStream);
67+
writer.Write(startFormData);
68+
writer.Flush();
69+
requestStream.Write(imageBinary, 0, imageBinary.Length);
70+
writer.Write(endFormData);
71+
writer.Flush();
72+
writer.Close();
6473
}
6574

66-
Console.Write("\nPress Enter to exit ");
67-
Console.ReadLine();
75+
// Calls the Bing Visual Search endpoint and returns the JSON response.
76+
HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
77+
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
78+
79+
Console.WriteLine("\nJSON Response:\n");
80+
dynamic parsedJson = JsonConvert.DeserializeObject(json);
81+
Console.WriteLine(JsonConvert.SerializeObject(parsedJson, Formatting.Indented));
6882
}
6983
catch (Exception e)
7084
{
7185
Console.WriteLine(e.Message);
7286
}
7387
}
74-
75-
76-
77-
/// <summary>
78-
/// Verify that imagePath exists.
79-
/// </summary>
80-
static Boolean IsImagePathSet(string path)
81-
{
82-
if (string.IsNullOrEmpty(path))
83-
throw new ArgumentException("Image path is null or empty.");
84-
85-
if (!File.Exists(path))
86-
throw new ArgumentException("Image path does not exist.");
87-
88-
var size = new FileInfo(path).Length;
89-
90-
if (size > 1000000)
91-
throw new ArgumentException("Image is greater than the 1 MB maximum size.");
92-
93-
return true;
94-
}
95-
96-
97-
98-
/// <summary>
99-
/// Get the binary characters of an image.
100-
/// </summary>
101-
static byte[] GetImageBinary(string path)
102-
{
103-
return File.ReadAllBytes(path);
104-
}
105-
106-
107-
/// <summary>
108-
/// Get the image's filename.
109-
/// </summary>
110-
static string GetImageFileName(string path)
111-
{
112-
return new FileInfo(path).Name;
113-
}
114-
115-
116-
/// <summary>
117-
/// Build the beginning part of the form data.
118-
/// </summary>
119-
static string BuildFormDataStart(string boundary, string filename)
120-
{
121-
var startBoundary = string.Format(StartBoundaryTemplate, boundary);
122-
123-
var requestBody = startBoundary + CRLF;
124-
requestBody += string.Format(POST_BODY_DISPOSITION_HEADER, filename);
125-
126-
return requestBody;
127-
}
128-
129-
130-
/// <summary>
131-
/// Build the ending part of the form data.
132-
/// </summary>
133-
static string BuildFormDataEnd(string boundary)
134-
{
135-
return CRLF + CRLF + string.Format(EndBoundaryTemplate, boundary) + CRLF;
136-
}
137-
138-
139-
140-
/// <summary>
141-
/// Calls the Bing visual search endpoint and returns the JSON response.
142-
/// </summary>
143-
static string BingImageSearch(string startFormData, string endFormData, byte[] image, string contentTypeValue)
144-
{
145-
WebRequest request = HttpWebRequest.Create(uriBase);
146-
request.ContentType = contentTypeValue;
147-
request.Headers["Ocp-Apim-Subscription-Key"] = accessKey;
148-
request.Method = "POST";
149-
150-
// Writes the boundary and Content-Disposition header, then writes
151-
// the image binary, and finishes by writing the closing boundary.
152-
using (Stream requestStream = request.GetRequestStream())
153-
{
154-
StreamWriter writer = new StreamWriter(requestStream);
155-
writer.Write(startFormData);
156-
writer.Flush();
157-
requestStream.Write(image, 0, image.Length);
158-
writer.Write(endFormData);
159-
writer.Flush();
160-
writer.Close();
161-
}
162-
163-
164-
HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
165-
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
166-
167-
return json;
168-
}
169-
170-
171-
/// <summary>
172-
/// Formats the given JSON string by adding line breaks and indents.
173-
/// </summary>
174-
/// <param name="json">The raw JSON string to format.</param>
175-
/// <returns>The formatted JSON string.</returns>
176-
static string JsonPrettyPrint(string json)
177-
{
178-
if (string.IsNullOrEmpty(json))
179-
return string.Empty;
180-
181-
json = json.Replace(Environment.NewLine, "").Replace("\t", "");
182-
183-
StringBuilder sb = new StringBuilder();
184-
bool quote = false;
185-
bool ignore = false;
186-
char last = ' ';
187-
int offset = 0;
188-
int indentLength = 2;
189-
190-
foreach (char ch in json)
191-
{
192-
switch (ch)
193-
{
194-
case '"':
195-
if (!ignore) quote = !quote;
196-
break;
197-
case '\\':
198-
if (quote && last != '\\') ignore = true;
199-
break;
200-
}
201-
202-
if (quote)
203-
{
204-
sb.Append(ch);
205-
if (last == '\\' && ignore) ignore = false;
206-
}
207-
else
208-
{
209-
switch (ch)
210-
{
211-
case '{':
212-
case '[':
213-
sb.Append(ch);
214-
sb.Append(Environment.NewLine);
215-
sb.Append(new string(' ', ++offset * indentLength));
216-
break;
217-
case '}':
218-
case ']':
219-
sb.Append(Environment.NewLine);
220-
sb.Append(new string(' ', --offset * indentLength));
221-
sb.Append(ch);
222-
break;
223-
case ',':
224-
sb.Append(ch);
225-
sb.Append(Environment.NewLine);
226-
sb.Append(new string(' ', offset * indentLength));
227-
break;
228-
case ':':
229-
sb.Append(ch);
230-
sb.Append(' ');
231-
break;
232-
default:
233-
if (quote || ch != ' ') sb.Append(ch);
234-
break;
235-
}
236-
}
237-
last = ch;
238-
}
239-
240-
return sb.ToString().Trim();
241-
}
24288
}
24389
}

0 commit comments

Comments
 (0)