Udostępnij za pośrednictwem


Samouczek: przekazywanie obrazów do interfejsu API wyszukiwania wizualnego Bing

Ostrzeżenie

30 października 2020 r. interfejsy API wyszukiwania Bing zostały przeniesione z usług Azure AI do usług wyszukiwania Bing. 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 wyszukiwania Bing za pośrednictwem witryny Azure Marketplace.

Interfejs API wyszukiwania wizualnego Bing umożliwia wyszukiwanie w Internecie obrazów podobnych do tych, które przesyłasz. Przy użyciu tego samouczka możesz utworzyć aplikację internetową, która wysyła obraz do interfejsu API i wyświetla wyniki na stronie internetowej. Należy pamiętać, że ta aplikacja nie jest zgodna ze wszystkimi wymaganiom Bing dotyczącym użycia i wyświetlania podczas korzystania z API.

Pełny kod źródłowy dla tego przykładu można znaleźć z dodatkową obsługą błędów i adnotacjami w usłudze GitHub.

Aplikacja samouczka ilustruje sposób wykonywania następujących czynności:

  • Prześlij obraz do interfejsu API wyszukiwania wizualnego Bing
  • Wyświetlanie wyników wyszukiwania obrazu w aplikacji internetowej
  • Odkryj różne spostrzeżenia dostarczone za pomocą API

Wymagania wstępne

Tworzenie zasobu platformy Azure

Rozpocznij korzystanie z interfejsu API wyszukiwania wizualnego Bing, tworząc jeden z następujących zasobów platformy Azure:

Zasób wyszukiwania Bing w wersji 7

  • Dostępne za pośrednictwem witryny Azure Portal do momentu usunięcia zasobu.
  • Wybierz warstwę cenową S9 .

Zasób z wieloma usługami

  • Dostępne za pośrednictwem witryny 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 strony internetowej i określanie jej struktury

Utwórz stronę HTML, która wysyła obraz do interfejsu API wyszukiwania wizualnego Bing, odbiera szczegółowe informacje i wyświetla je. W ulubionym edytorze lub środowisku IDE utwórz plik o nazwie "uploaddemo.html". Dodaj następującą podstawową strukturę HTML do pliku:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Visual Search Upload Demo</title>
    </head>

    <body>
    </body>
</html>

Podziel stronę na sekcję żądania, w której użytkownik udostępnia wszystkie informacje wymagane dla żądania oraz sekcję odpowiedzi, w której są wyświetlane szczegółowe informacje. Dodaj następujące tagi <div> do sekcji <body>. Tag <hr> wizualnie oddziela sekcję żądania od sekcji odpowiedzi:

<div id="requestSection"></div>
<hr />
<div id="responseSection"></div>

<script> Dodaj tag do tagu<head>, aby zawierał kod JavaScript dla aplikacji:

<script>
<\script>

Uzyskaj plik do przesłania

Aby umożliwić użytkownikowi wybranie obrazu do przekazania, aplikacja używa tagu <input> z atrybutem type o wartości file. Interfejs użytkownika musi w jasny sposób poinformować, że w aplikacji do wyszukiwania wyników jest używana usługa Bing.

Dodaj następujący kod <div> do pliku requestSection<div>. Pole wyboru pliku akceptuje pojedynczy plik dowolnego typu obrazu (na przykład .jpg, .gif, .png). Zdarzenie onchange określa procedurę obsługi, która jest wywoływana, gdy użytkownik wybiera plik.

Tag <output> służy do wyświetlania miniatury wybranego obrazu:

<div>
    <p>Select image to get insights from Bing:
        <input type="file" accept="image/*" id="uploadImage" name="files[]" size=40 onchange="handleFileSelect('uploadImage')" />
    </p>

    <output id="thumbnail"></output>
</div>

Utwórz procedurę obsługi plików

Utwórz funkcję obsługi mogącą odczytać obraz, który chcesz przesłać. Podczas iterowania po plikach w obiekcie FileList procedura obsługi powinna sprawdzić, czy wybrany plik jest obrazem, a jego rozmiar to 1 MB lub mniej. Jeśli obraz jest większy, przed przekazaniem go należy zmniejszyć jego rozmiar. Na koniec program obsługi wyświetla miniaturę obrazu:

function handleFileSelect(selector) {

    var files = document.getElementById(selector).files; // A FileList object

    for (var i = 0, f; f = files[i]; i++) {

        // Ensure the file is an image file.
        if (!f.type.match('image.*')) {
            alert("Selected file must be an image file.");
            document.getElementById("uploadImage").value = null;
            continue;
        }

        // Image must be <= 1 MB and should be about 1500px.
        if (f.size > 1000000) {
            alert("Image must be less than 1 MB.");
            document.getElementById("uploadImage").value = null;
            continue;
        }

        var reader = new FileReader();

        // Capture the file information.
        reader.onload = (function(theFile) {
            return function(e) {
                var fileOutput = document.getElementById('thumbnail');

                if (fileOutput.childElementCount > 0) {
                    fileOutput.removeChild(fileOutput.lastChild);  // Remove the current pic, if it exists
                }

                // Render thumbnail.
                var span = document.createElement('span');
                span.innerHTML = ['<img class="thumb" src="', e.target.result,
                                    '" title="', escape(theFile.name), '"/>'].join('');
                fileOutput.insertBefore(span, null);
            };
        })(f);

        // Read in the image file as a data URL.
        reader.readAsDataURL(f);
    }
}

Dodawanie i przechowywanie klucza subskrypcji

Aplikacja wymaga klucza subskrypcji, aby wykonywać wywołania interfejsu API wyszukiwania wizualnego Bing. Na potrzeby tego samouczka podasz go w interfejsie użytkownika. Dodaj następujący <input> tag (z atrybutem type ustawionym na tekst) do <body> poniższego tagu <output> pliku:

    <div>
        <p>Subscription key: 
            <input type="text" id="key" name="subscription" size=40 maxlength="32" />
        </p>
    </div>

Korzystając z obrazu i klucza subskrypcji, możesz wywołać usługę wyszukiwania wizualnego Bing, aby pobrać szczegółowe informacje o obrazie. W tym samouczku wywołanie korzysta z domyślnego rynku (en-us) oraz wartości bezpiecznego wyszukiwania (moderate).

Ta aplikacja zawiera opcję zmiany tych wartości. Dodaj następujący kod <div> poniżej klucza <div>subskrypcji . W aplikacji używany jest tag <select> aby zapewnić listę rozwijaną dla wartości rynku oraz bezpiecznego wyszukiwania. Obie listy wyświetlają domyślną wartość.

<div>
    <p><a href="#" onclick="expandCollapse(options.id)">Query options</a></p>

    <div id="options" style="display:none">
        <p style="margin-left: 20px">Market: 
            <select id="mkt">
                <option value="es-AR">Argentina (Spanish)</option>
                <option value="en-AU">Australia (English)</option>
                <option value="de-AT">Austria (German)</option>
                <option value="nl-BE">Belgium (Dutch)</option>
                <option value="fr-BE">Belgium (French)</option>
                <option value="pt-BR">Brazil (Portuguese)</option>
                <option value="en-CA">Canada (English)</option>
                <option value="fr-CA">Canada (French)</option>
                <option value="es-CL">Chile (Spanish)</option>
                <option value="da-DK">Denmark (Danish)</option>
                <option value="fi-FI">Finland (Finnish)</option>
                <option value="fr-FR">France (French)</option>
                <option value="de-DE">Germany (German)</option>
                <option value="zh-HK">Hong Kong SAR(Traditional Chinese)</option>
                <option value="en-IN">India (English)</option>
                <option value="en-ID">Indonesia (English)</option>
                <option value="it-IT">Italy (Italian)</option>
                <option value="ja-JP">Japan (Japanese)</option>
                <option value="ko-KR">Korea (Korean)</option>
                <option value="en-MY">Malaysia (English)</option>
                <option value="es-MX">Mexico (Spanish)</option>
                <option value="nl-NL">Netherlands (Dutch)</option>
                <option value="en-NZ">New Zealand (English)</option>
                <option value="no-NO">Norway (Norwegian)</option>
                <option value="zh-CN">People's Republic of China (Chinese)</option>
                <option value="pl-PL">Poland (Polish)</option>
                <option value="pt-PT">Portugal (Portuguese)</option>
                <option value="en-PH">Philippines (English)</option>
                <option value="ru-RU">Russia (Russian)</option>
                <option value="ar-SA">Saudi Arabia (Arabic)</option>
                <option value="en-ZA">South Africa (English)</option>
                <option value="es-ES">Spain (Spanish)</option>
                <option value="sv-SE">Sweden (Swedish)</option>
                <option value="fr-CH">Switzerland (French)</option>
                <option value="de-CH">Switzerland (German)</option>
                <option value="zh-TW">Taiwan (Traditional Chinese)</option>
                <option value="tr-TR">Türkiye (Turkish)</option>
                <option value="en-GB">United Kingdom (English)</option>
                <option value="en-US" selected>United States (English)</option>
                <option value="es-US">United States (Spanish)</option>
            </select>
        </p>
        <p style="margin-left: 20px">Safe search: 
            <select id="safesearch">
                <option value="moderate" selected>Moderate</option>
                <option value="strict">Strict</option>
                <option value="off">off</option>
            </select>
        </p>
    </div>
</div>

Dodawanie opcji wyszukiwania na stronie internetowej

Aplikacja ukrywa listy w zwijanym <div> obszarze kontrolowanym przez odnośnik Opcje zapytania. Po kliknięciu linku Opcje zapytania <div> zostanie rozwinięte, aby wyświetlić i zmodyfikować opcje zapytania. Jeśli ponownie klikniesz link "Opcje zapytania", <div> zostanie zwinięty i ukryty. Poniższy fragment kodu przedstawia procedurę obsługi linku opcji zapytania onclick. Program obsługi określa, czy <div> jest rozwinięty, czy zwinięty. Dodaj tę procedurę obsługi do sekcji <script>. Procedura obsługi jest używana przez wszystkie zwijane <div> sekcje w demonstracji.

// Contains the toggle state of divs.
var divToggleMap = {};  // divToggleMap['foo'] = 0;  // 1 = show, 0 = hide


// Toggles between showing and hiding the specified div.
function expandCollapse(divToToggle) {
    var div = document.getElementById(divToToggle);

    if (divToggleMap[divToToggle] == 1) {   // if div is expanded
        div.style.display = "none";
        divToggleMap[divToToggle] = 0;
    }
    else {                                  // if div is collapsed
        div.style.display = "inline-block";
        divToggleMap[divToToggle] = 1;
    }
}

Zadzwoń do onclick programu obsługi

Dodaj następujący przycisk "Get insights" poniżej opcji <div> w głównej części. Przycisk umożliwia rozpoczęcie połączenia. Po kliknięciu przycisku kursor jest zmieniany na kursor oczekiwania z obracającym się kółkiem, a onclick procedura obsługi jest wywoływana.

<p><input type="button" id="query" value="Get insights" onclick="document.body.style.cursor='wait'; handleQuery()" /></p>

Dodaj procedurę obsługi przycisku onclickhandleQuery() do tagu <script>.

Obsługa zapytania

Procedura obsługi handleQuery() gwarantuje, że klucz subskrypcji jest obecny i ma długość 32 znaków oraz że wybrano obraz. Ponadto usuwa wszelkie spostrzeżenia z poprzedniego zapytania. Następnie wywołuje funkcję sendRequest(), aby wykonać wywołanie.

function handleQuery() {
    var subscriptionKey = document.getElementById('key').value;

    // Make sure user provided a subscription key and image.
    // For this demo, the user provides the key but typically you'd
    // get it from secured storage.
    if (subscriptionKey.length !== 32) {
        alert("Subscription key length is not valid. Enter a valid key.");
        document.getElementById('key').focus();
        return;
    }

    var imagePath = document.getElementById('uploadImage').value;

    if (imagePath.length === 0)
    {
        alert("Please select an image to upload.");
        document.getElementById('uploadImage').focus();
        return;
    }

    var responseDiv = document.getElementById('responseSection');

    // Clear out the response from the last query.
    while (responseDiv.childElementCount > 0) {
        responseDiv.removeChild(responseDiv.lastChild);
    }

    // Send the request to Bing to get insights about the image.
    var f = document.getElementById('uploadImage').files[0];
    sendRequest(f, subscriptionKey);
}

Wysyłanie żądania wyszukiwania

Funkcja sendRequest() formatuje URL punktu końcowego, ustawia nagłówek Ocp-Apim-Subscription-Key na klucz subskrypcji, dołącza binarny obraz do przesłania, określa procedurę obsługi odpowiedzi i wykonuje wywołanie:

function sendRequest(file, key) {
    var market = document.getElementById('mkt').value;
    var safeSearch = document.getElementById('safesearch').value;
    var baseUri = `https://api.cognitive.microsoft.com/bing/v7.0/images/visualsearch?mkt=${market}&safesearch=${safeSearch}`;

    var form = new FormData();
    form.append("image", file);

    var request = new XMLHttpRequest();

    request.open("POST", baseUri);
    request.setRequestHeader('Ocp-Apim-Subscription-Key', key);
    request.addEventListener('load', handleResponse);
    request.send(form);
}

Pobieranie i obsługa odpowiedzi interfejsu API

Funkcja handleResponse() obsługuje odpowiedź z wywołania wyszukiwania wizualnego Bing. Jeśli wywołanie zakończy się powodzeniem, odpowiedź JSON jest analizowana i rozdzielana na poszczególne tagi, które zawierają informacje. Następnie dodaje wyniki wyszukiwania do strony. Następnie aplikacja tworzy zwijany <div> dla każdego tagu, aby zarządzać ilością wyświetlanych danych. Dodaj tę procedurę obsługi do sekcji <script>.

function handleResponse() {
    if(this.status !== 200){
        alert("Error calling Bing Visual Search. See console log for details.");
        console.log(this.responseText);
        return;
    }

    var tags = parseResponse(JSON.parse(this.responseText));
    var h4 = document.createElement('h4');
    h4.textContent = 'Bing internet search results';
    document.getElementById('responseSection').appendChild(h4);
    buildTagSections(tags);

    document.body.style.cursor = 'default'; // reset the wait cursor set by query insights button
}

Analizowanie odpowiedzi

Funkcja parseResponse konwertuje odpowiedź JSON do obiektu słownika przez iterację po pliku json.tags.

function parseResponse(json) {
    var dict = {};

    for (var i =0; i < json.tags.length; i++) {
        var tag = json.tags[i];

        if (tag.displayName === '') {
            dict['Default'] = JSON.stringify(tag);
        }
        else {
            dict[tag.displayName] = JSON.stringify(tag);
        }
    }

    return(dict);
}

Tworzenie sekcji tagów

Funkcja buildTagSections() iteruje po przeanalizowanych tagach JSON i wywołuje funkcję buildDiv() w celu utworzenia <div> dla każdego tagu. Każdy tag jest wyświetlany jako link. Gdy link zostanie kliknięty, tag rozwinie się i wyświetli skojarzone z nim szczegółowe informacje. Ponowne kliknięcie linku powoduje zwinięcie sekcji.

function buildTagSections(tags) {
    for (var tag in tags) {
        if (tags.hasOwnProperty(tag)) {
            var tagSection = buildDiv(tags, tag);
            document.getElementById('responseSection').appendChild(tagSection);
        }
    }  
}

function buildDiv(tags, tag) {
    var tagSection = document.createElement('div');
    tagSection.setAttribute('class', 'subSection');

    var link = document.createElement('a');
    link.setAttribute('href', '#');
    link.setAttribute('style', 'float: left;')
    link.text = tag;
    tagSection.appendChild(link);

    var contentDiv = document.createElement('div');
    contentDiv.setAttribute('id', tag);
    contentDiv.setAttribute('style', 'clear: left;')
    contentDiv.setAttribute('class', 'section');
    tagSection.appendChild(contentDiv);

    link.setAttribute('onclick', `expandCollapse("${tag}")`);
    divToggleMap[tag] = 0;  // 1 = show, 0 = hide

    addDivContent(contentDiv, tag, tags[tag]);

    return tagSection;
}

Wyświetlanie wyników wyszukiwania na stronie internetowej

Funkcja buildDiv() wywołuje funkcję addDivContent w celu zbudowania zawartości zwijanego tagu <div>.

Zawartość tagu zawiera dane JSON z odpowiedzi dla tagu. Początkowo wyświetlane są tylko pierwsze 100 znaków w formacie JSON, ale możesz kliknąć ciąg JSON, aby wyświetlić wszystkie dane JSON. Jeśli klikniesz go ponownie, ciąg JSON ponownie zwinie się do 100 znaków.

Następnie dodaj typy akcji znalezione w tagu. Dla każdego typu akcji wywołaj odpowiednie funkcje, aby dodać szczegółowe informacje:

function addDivContent(div, tag, json) {

    // Adds the first 100 characters of the json that contains
    // the tag's data. The user can click the text to show the
    // full json. They can click it again to collapse the json.
    var para = document.createElement('p');
    para.textContent = String(json).substr(0, 100) + '...';
    para.setAttribute('title', 'click to expand');
    para.setAttribute('style', 'cursor: pointer;')
    para.setAttribute('data-json', json);
    para.addEventListener('click', function(e) {
        var json = e.target.getAttribute('data-json');

        if (e.target.textContent.length <= 103) {  // 100 + '...'
            e.target.textContent = json;
            para.setAttribute('title', 'click to collapse');
        }
        else {
            para.textContent = String(json).substr(0, 100) + '...';
            para.setAttribute('title', 'click to expand');
        }
    });
    div.appendChild(para); 

    var parsedJson = JSON.parse(json);

    // Loop through all the actions in the tag and display them.
    for (var j = 0; j < parsedJson.actions.length; j++) {
        var action = parsedJson.actions[j];

        var subSectionDiv = document.createElement('div');
        subSectionDiv.setAttribute('class', 'subSection');
        div.appendChild(subSectionDiv);

        var h4 = document.createElement('h4');
        h4.innerHTML = action.actionType;
        subSectionDiv.appendChild(h4);

        if (action.actionType === 'ImageResults') {
            addImageWithWebSearchUrl(subSectionDiv, parsedJson.image, action);
        }
        else if (action.actionType === 'DocumentLevelSuggestions') {
            addRelatedSearches(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'RelatedSearches') {
            addRelatedSearches(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'PagesIncluding') {
            addPagesIncluding(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'VisualSearch') {
            addRelatedImages(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'Recipes') {
            addRecipes(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'ShoppingSources') {
            addShopping(subSectionDiv, action.data.offers);
        }
        else if (action.actionType === 'ProductVisualSearch') {
            addProducts(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'TextResults') {
            addTextResult(subSectionDiv, action);
        }
        else if (action.actionType === 'Entity') {
            addEntity(subSectionDiv, action);
        }
    }
}

Wyświetlanie szczegółowych informacji dla różnych akcji

Następujące funkcje wyświetlają szczegółowe informacje dla różnych akcji. Funkcje zapewniają klikalny obraz albo klikalny link, który prowadzi do strony internetowej z dodatkowymi informacjami na temat obrazu. Ta strona jest hostowana przez Bing.com lub oryginalną witrynę internetową obrazu. Nie wszystkie dane z analiz są wyświetlane w tej aplikacji. Aby zobaczyć wszystkie pola dostępne dla wglądu, zajrzyj do referencji Obrazy — wyszukiwanie wizualne.

Uwaga

Obowiązuje minimalna ilość szczegółowych informacji, którą należy wyświetlić na stronie. Aby uzyskać więcej informacji, zobacz wymagania dotyczące używania i wyświetlania interfejsu API wyszukiwania Bing .

Wnioski dotyczące RelatedImages

Funkcja addRelatedImages() tworzy tytuł dla każdej z witryn internetowych hostujących powiązany obraz, przechodząc przez listę działań RelatedImages i dodając znacznik <img> na zewnątrz każdego <div>.

    function addRelatedImages(div, images) {
        var length = (images.length > 10) ? 10 : images.length;

        // Set the title to the website that hosts the image. The title displays
        // when the user hovers over the image.

        // Make the image clickable. If the user clicks the image, they're taken
        // to the image in Bing.com.

        for (var j = 0; j < length; j++) {
            var img = document.createElement('img');
            img.setAttribute('src', images[j].thumbnailUrl + '&w=120&h=120');
            img.setAttribute('style', 'margin: 20px 20px 0 0; cursor: pointer;');
            img.setAttribute('title', images[j].hostPageDisplayUrl);
            img.setAttribute('data-webSearchUrl', images[j].webSearchUrl)

            img.addEventListener('click', function(e) {
                var url = e.target.getAttribute('data-webSearchUrl');
                window.open(url, 'foo');
            })

            div.appendChild(img);
        }
    }

Szczegółowe analizy PagesIncluding

Funkcja addPagesIncluding() tworzy link dla każdej z witryn internetowych hostujących przekazany obraz, iterując przez listę PagesIncluding czynności i dodając tag <img> na zewnątrz struktury <div> dla każdej z nich.


    // Display links to the first 5 webpages that include the image.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addPagesIncluding(div, pages) {
        var length = (pages.length > 5) ? 5 : pages.length;

        for (var j = 0; j < length; j++) {
            var page = document.createElement('a');
            page.text = pages[j].name;
            page.setAttribute('href', pages[j].hostPageUrl);
            page.setAttribute('style', 'margin: 20px 20px 0 0');
            page.setAttribute('target', '_blank')
            div.appendChild(page);

            div.appendChild(document.createElement('br'));
        }
    }

Statystyki RelatedSearches

Funkcja addRelatedSearches() tworzy link dla witryny internetowej obsługującej obraz, iterując przez listę RelatedSearches akcji i dołączając <img> tag na zewnątrz <div> dla każdego z nich:


    // Display the first 10 related searches. Include a link with the image
    // that when clicked, takes the user to Bing.com and displays the 
    // related search results.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addRelatedSearches(div, relatedSearches) {
        var length = (relatedSearches.length > 10) ? 10 : relatedSearches.length;

        for (var j = 0; j < length; j++) {
            var childDiv = document.createElement('div');
            childDiv.setAttribute('class', 'stackLink');
            div.appendChild(childDiv);

            var img = document.createElement('img');
            img.setAttribute('src', relatedSearches[j].thumbnail.url + '&w=120&h=120');
            img.setAttribute('style', 'margin: 20px 20px 0 0;');
            childDiv.appendChild(img);

            var relatedSearch = document.createElement('a');
            relatedSearch.text = relatedSearches[j].displayText;
            relatedSearch.setAttribute('href', relatedSearches[j].webSearchUrl);
            relatedSearch.setAttribute('target', '_blank');
            childDiv.appendChild(relatedSearch);

        }
    }

Wskazówki dotyczące przepisów

Funkcja addRecipes() tworzy link dla każdego przepisu zwracanego podczas przeglądania listy akcji Recipes i dołączając tag <img> na zewnątrz <div> dla każdego z nich:

    // Display links to the first 10 recipes. Include the recipe's rating,
    // if available.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addRecipes(div, recipes) {
        var length = (recipes.length > 10) ? 10 : recipes.length;

        for (var j = 0; j < length; j++) {
            var para = document.createElement('p');

            var recipe = document.createElement('a');
            recipe.text = recipes[j].name;
            recipe.setAttribute('href', recipes[j].url);
            recipe.setAttribute('style', 'margin: 20px 20px 0 0');
            recipe.setAttribute('target', '_blank')
            para.appendChild(recipe);

            if (recipes[j].hasOwnProperty('aggregateRating')) {
                var span = document.createElement('span');
                span.textContent = 'rating: ' + recipes[j].aggregateRating.text;
                para.appendChild(span);
            }

            div.appendChild(para);
        }
    }

Szczegółowe informacje dotyczące zakupów

Funkcja addShopping() tworzy link dla dowolnych zwróconych wyników zakupów, iterując przez listę RelatedImages akcji i dołączając tag <img> do zewnętrznego <div> dla każdej akcji:

    // Display links for the first 10 shopping offers.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addShopping(div, offers) {
        var length = (offers.length > 10) ? 10 : offers.length;

        for (var j = 0; j < length; j++) {
            var para = document.createElement('p');

            var offer = document.createElement('a');
            offer.text = offers[j].name;
            offer.setAttribute('href', offers[j].url);
            offer.setAttribute('style', 'margin: 20px 20px 0 0');
            offer.setAttribute('target', '_blank')
            para.appendChild(offer);

            var span = document.createElement('span');
            span.textContent = 'by ' + offers[j].seller.name + ' | ' + offers[j].price + ' ' + offers[j].priceCurrency;
            para.appendChild(span);

            div.appendChild(para);
        }
    }

Szczegółowe informacje dotyczące produktów

Funkcja addProducts() tworzy link dla dowolnych wyników zwróconych produktów, iterując przez listę Products akcji i dodając tag <img> na zewnątrz <div> dla każdego z nich.


    // Display the first 10 related products. Display a clickable image of the
    // product that takes the user to Bing.com search results for the product.
    // If there are any offers associated with the product, provide links to the offers.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addProducts(div, products) {
        var length = (products.length > 10) ? 10 : products.length;

        for (var j = 0; j < length; j++) {
            var childDiv = document.createElement('div');
            childDiv.setAttribute('class', 'stackLink');
            div.appendChild(childDiv);

            var img = document.createElement('img');
            img.setAttribute('src', products[j].thumbnailUrl + '&w=120&h=120');
            img.setAttribute('title', products[j].name);
            img.setAttribute('style', 'margin: 20px 20px 0 0; cursor: pointer;');
            img.setAttribute('data-webSearchUrl', products[j].webSearchUrl)
            img.addEventListener('click', function(e) {
                var url = e.target.getAttribute('data-webSearchUrl');
                window.open(url, 'foo');
            })
            childDiv.appendChild(img);

            if (products[j].insightsMetadata.hasOwnProperty('aggregateOffer')) {
                if (products[j].insightsMetadata.aggregateOffer.offerCount > 0) {
                    var offers = products[j].insightsMetadata.aggregateOffer.offers;

                    // Show all the offers. Not all markets provide links to offers.
                    for (var i = 0; i < offers.length; i++) {  
                        var para = document.createElement('p');

                        var offer = document.createElement('a');
                        offer.text = offers[i].name;
                        offer.setAttribute('href', offers[i].url);
                        offer.setAttribute('style', 'margin: 20px 20px 0 0');
                        offer.setAttribute('target', '_blank')
                        para.appendChild(offer);

                        var span = document.createElement('span');
                        span.textContent = 'by ' + offers[i].seller.name + ' | ' + offers[i].price + ' ' + offers[i].priceCurrency;
                        para.appendChild(span);

                        childDiv.appendChild(para);
                    }
                }
                else {  // Otherwise, just show the lowest price that Bing found.
                    var offer = products[j].insightsMetadata.aggregateOffer;

                    var para = document.createElement('p');
                    para.textContent = `${offer.name} | ${offer.lowPrice} ${offer.priceCurrency}`; 

                    childDiv.appendChild(para);
                }
            }
        }
    }

Spostrzeżenia dotyczące TextResult

Funkcja addTextResult() wyświetla dowolny tekst rozpoznany na obrazie:


    function addTextResult(div, action) {
        var text = document.createElement('p');
        text.textContent = action.displayName;
        div.appendChild(text);
    }

Funkcja addEntity() wyświetla link, który przenosi użytkownika na Bing.com, gdzie może uzyskać szczegółowe informacje o typie bytu na obrazie, jeśli jakiś został wykryty.

    // If the image is of a person, the tag might include an entity
    // action type. Display a link that takes the user to Bing.com
    // where they can get details about the entity.
    function addEntity(div, action) {
        var entity = document.createElement('a');
        entity.text = action.displayName;
        entity.setAttribute('href', action.webSearchUrl);
        entity.setAttribute('style', 'margin: 20px 20px 0 0');
        entity.setAttribute('target', '_blank');
        div.appendChild(entity);
    }

Funkcja addImageWithWebSearchUrl() wyświetla klikalny obraz <div>, który prowadzi użytkownika do wyników wyszukiwania na Bing.com.

    function addImageWithWebSearchUrl(div, image, action) {
        var img = document.createElement('img');
        img.setAttribute('src', image.thumbnailUrl + '&w=120&h=120');
        img.setAttribute('style', 'margin: 20px 20px 0 0; cursor: pointer;');
        img.setAttribute('data-webSearchUrl', action.webSearchUrl);
        img.addEventListener('click', function(e) {
            var url = e.target.getAttribute('data-webSearchUrl');
            window.open(url, 'foo');
        })
        div.appendChild(img);
    }

Dodawanie stylu CSS

Dodaj następującą <style> sekcję do tagu <head> , aby zorganizować układ strony internetowej:

        <style>

            .thumb {
                height: 75px;
                border: 1px solid #000;
            }

            .stackLink {
                width:180px;
                min-height:210px;
                display:inline-block;
            }
            .stackLink a {
                float:left;
                clear:left;
            }

            .section {
                float:left;
                display:none;
            }

            .subSection {
                clear:left;
                float:left;
            }

        </style>

Następne kroki