Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Use this quickstart to make your first call to the Bing Visual Search API using the Go programming language. A POST request uploads an image to the API endpoint. The results include URLs and descriptive information about images similar to the uploaded image.
Prerequisites
- Install the Go binaries.
- Install the go-spew deep pretty printer, which is used to display results. To install go-spew, use the
$ go get -u https://github.com/davecgh/go-spewcommand.
Project and libraries
Create a Go project in your IDE or editor. Then, import net/http for requests, ioutil to read the response, and encoding/json to handle the JSON text of results. Use the go-spew library to parse JSON results.
package main
import (
"bytes"
"io"
"fmt"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"encoding/json"
"github.com/davecgh/go-spew/spew"
)
Struct to format results
The BingAnswer structure formats data returned in the JSON response, which is multilevel and complex. The following implementation covers some of the essentials:
type BingAnswer struct {
Type string `json:"_type"`
Instrumentation struct {
Type string `json:"_type"`
PingUrlBase string `json:"_pingUrlBase"`
PageLoadPingUrl string `json:"_pageLoadPingUrl"`
} `json:"instrumentation"`
Tags []struct {
DisplayName string `json:"displayName"`
Actions []struct {
Type string `json:"_type"`
ActionType string `json:"actionType"`
Data struct {
Value []struct {
WebSearchUrl string `json:"webSearchUrl"`
Name string `json:"name"`
}`json:"value"`
ImageInsightsToken string `json:"imageInsightsToken"`
InsightsMetadata struct {
PagesIncludingCount int `json:"pagesIncludingCount"`
AvailableSizesCount int `json:"availableSizesCount"`
}
ImageId string `json:"imageId"`
AccentColor string `json:"accentColor"`
} `json:"data"`
} `json:"actions"`
} `json:"tags"`
Image struct {
WebSearchUrl string `json:"webSearchUrl"`
WebSearchUrlPingSuffix string `json:"webSearchUrlPingSuffix"`
Name string `json:"name"`
IsFamilyFriendly bool `json:"isFamilyFriendly"`
ContentSize string `json:"contentSize"`
EncodingFormat string `json:"encodingFormat"`
HostPageDisplayUrl string `json:"hostPageDisplayUrl"`
Width int `json:"width"`
Height int `json:"height"`
Thumbnail struct {
Width int `json:"width"`
Height int `json:"height"`
}
InsightsMetadata struct {
PagesIncludingCount int `json:"pagesIncludingCount"`
AvailableSizesCount int `json:"availableSizesCount"`
}
AccentColor string `json:"accentColor"`
VisualWords string `json:"visualWords"`
} `json:"image"`
}
Main function and variables
The following code declares the main function and assigns the required variables:
- Confirm that the endpoint is correct and replace the
tokenvalue with a valid subscription key from your Azure account. - For
batchNumber, assign a GUID, which is required for the leading and trailing boundaries of the POST data. - For
fileName, assign the image file to use for the POST.
func main() {
// Verify the endpoint URI and replace the token string with a valid subscription key.se
endpoint := "https://api.bing.microsoft.com/bing/v7.0/images/visualsearch"
token := "YOUR-ACCESS-KEY"
client := &http.Client{}
batchNumber := "d7ecc447-912f-413e-961d-a83021f1775f"
fileName := "ElectricBike.JPG"
body, contentType := createRequestBody(fileName, batchNumber)
req, err := http.NewRequest("POST", endpoint, body)
req.Header.Add("Content-Type", contentType)
req.Header.Set("Ocp-Apim-Subscription-Key", token)
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
resbody, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
//fmt.Print(string(resbody))
// Create a new answer.
ans := new(BingAnswer)
err = json.Unmarshal(resbody, &ans)
if err != nil {
fmt.Println(err)
}
fmt.Print("Output of BingAnswer: \r\n\r\n")
// Iterate over search results and print the result name and URL.
for _, result := range ans.Tags {
spew.Dump(result)
}
}
Boundaries of POST body
A POST request to the Visual Search endpoint requires leading and trailing boundaries to enclose the POST data. These functions aren't included in the main() block.
The leading boundary includes a batch number, the content type identifier Content-Disposition: form-data; name="image"; filename=, and the filename of the image to POST.
The trailing boundary includes the batch number only.
func BuildFormDataStart(batNum string, fileName string) string{
startBoundary := "--batch_" + batNum + "\r\n"
requestBoundary := startBoundary + "\r\n" + "Content-Disposition: form-data; name=\"image\"; filename=" + fileName + "\r\n\r\n"
return requestBoundary
}
func BuildFormDataEnd(batNum string) string{
return "\r\n" + "\r\n" + "--batch_" + batNum + "\r\n"
}
Add image bytes to POST body
The following code creates the POST request that contains image data:
func createRequestBody(fileName string, batchNumber string) (*bytes.Buffer, string) {
file, err := os.Open(fileName)
if err != nil {
panic(err)
}
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
writer.SetBoundary(BuildFormDataStart(batchNumber, fileName))
part, err := writer.CreateFormFile("image", filepath.Base(file.Name()))
if err != nil {
panic(err)
}
io.Copy(part, file)
writer.WriteField("lastpart", BuildFormDataEnd(batchNumber))
writer.Close()
return body, writer.FormDataContentType()
}
Send the request
The following code sends the request and reads the results:
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
resbody, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
Handle the response
The Unmarshall function extracts information from the JSON text returned by the Visual Search API. The go-spew pretty printer displays the results.
// Create a new answer.
ans := new(BingAnswer)
err = json.Unmarshal(resbody, &ans)
if err != nil {
fmt.Println(err)
}
fmt.Print("Output of BingAnswer: \r\n\r\n")
// Iterate over search results and print the result name and URL.
for _, result := range ans.Tags {
spew.Dump(result)
}
Note
Francesco Giordano contributed code to this example.
Results
The results identify images similar to the image contained in the POST body. The useful fields are WebSearchUrl and Name.
Value: ([]struct { WebSearchUrl string "json:\"webSearchUrl\""; Name string "json:\"name\"" }) (len=66 cap=94) {
(struct { WebSearchUrl string "json:\"webSearchUrl\""; Name string "json:\"name\"" }) {
WebSearchUrl: (string) (len=129) "https://www.bing.com/images/search?view=detailv2&FORM=OIIRPO&id=B9E6621161769D578A9E4DD9FD742128DE65225A&simid=608046863828453626",
Name: (string) (len=87) "26\"Foldable Electric Mountain Bike Bicycle Ebike W/Lithium Battery 250W 36V MY8L | eBay"
},
(struct { WebSearchUrl string "json:\"webSearchUrl\""; Name string "json:\"name\"" }) {
WebSearchUrl: (string) (len=129) "https://www.bing.com/images/search?view=detailv2&FORM=OIIRPO&id=5554757348A9E88E9EEAB74217E228689E716B61&simid=607988237543409883",
Name: (string) (len=96) "Best 25+ Electric mountain bike ideas on Pinterest | Mountain bicycle, Mtb mountain bike and ..."
},
(struct { WebSearchUrl string "json:\"webSearchUrl\""; Name string "json:\"name\"" }) {
WebSearchUrl: (string) (len=129) "https://www.bing.com/images/search?view=detailv2&FORM=OIIRPO&id=B56F626A4803D829FE326842E2B97CE5B87F17F2&simid=607991699288949513",
Name: (string) (len=100) "Electric Fat Bike Mountain Bicycle Snow Bike Cruiser Ebike Motor Lithium Battery Dual Oil Brakes ..."
},
(struct { WebSearchUrl string "json:\"webSearchUrl\""; Name string "json:\"name\"" }) {
WebSearchUrl: (string) (len=129) "https://www.bing.com/images/search?view=detailv2&FORM=OIIRPO&id=CCAE400EE510DCA6F5740ABAF08A5310B4EF0698&simid=608003854048890458",
Name: (string) (len=81) "Best Mountain Bikes Under 1500 (Outstanding Performance) | Mountain Bicycle World"
},
(struct { WebSearchUrl string "json:\"webSearchUrl\""; Name string "json:\"name\"" }) {
WebSearchUrl: (string) (len=129) "https://www.bing.com/images/search?view=detailv2&FORM=OIIRPO&id=1244730E2E3F2D5DFBED9A9CFE1DBE27B09F08BC&simid=608005181199745622",
Name: (string) (len=98) "ANCHEER Folding Electric Mountain Bike with 26\" Super Lightweight Magnesium (36V 250W) - GearScoot"
},
(struct { WebSearchUrl string "json:\"webSearchUrl\""; Name string "json:\"name\"" }) {
WebSearchUrl: (string) (len=129) "https://www.bing.com/images/search?view=detailv2&FORM=OIIRPO&id=38AAD876E57BB0D502FBDD5B1CB29EB7EB8DD9E2&simid=608041654062220328",
Name: (string) (len=97) "29 best CB Bikes Gadgets & Accessories images on Pinterest | Bicycles, Bicycling and Bike gadgets"
},
(struct { WebSearchUrl string "json:\"webSearchUrl\""; Name string "json:\"name\"" }) {
WebSearchUrl: (string) (len=129) "https://www.bing.com/images/search?view=detailv2&FORM=OIIRPO&id=6892C8FD22D0E42911C99AFD8FE1FD37BD82E02C&simid=608052803759703185",
Name: (string) (len=98) "ANCHEER Folding Electric Mountain Bike with 26\" Super Lightweight Magnesium (36V 250W) - GearScoot"
},