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 zostaną przekazane. 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. Pamiętaj, że ta aplikacja nie spełnia wszystkich wymagań dotyczących użycia i wyświetlania Bing dla używania interfejsu 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:

  • Przekazywanie obrazu do interfejsu API wyszukiwania wizualnego Bing
  • Wyświetlanie wyników wyszukiwania obrazu w aplikacji internetowej
  • Przeglądanie szczegółowych informacji dostarczonych przez interfejs 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>

Pobieranie pliku przekazywania

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>. Tag input z atrybutem type o wartości file 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>

Tworzenie procedury obsługi plików

Utwórz funkcję obsługi mogącą odczytać obraz, który chcesz przekazać. 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 używa domyślnego rynku (en-us) i 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 jest używany tag <select> do zapewnienia listy rozwijanej do określenia wartości rynku i wartości 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 link Opcje zapytania. Po kliknięciu linku Opcje zapytania zostanie rozwinięte, <div> aby wyświetlić i zmodyfikować opcje zapytania. Jeśli ponownie klikniesz link Opcje zapytania, <div> zwija się i jest ukryty. Poniższy fragment kodu przedstawia procedurę obsługi linków onclick opcji zapytania. Program obsługi określa, czy <div> obiekt 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 pokazie.

// 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;
    }
}

Wywoływanie onclick programu obsługi

Dodaj poniższy "Get insights" przycisk poniżej opcji <div> w treści. Przycisk umożliwia zainicjowanie wywołania. Po kliknięciu przycisku kursor jest zmieniany na obracający się kursor oczekiwania, a onclick program obsługi jest wywoływany.

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

Dodaj procedurę obsługi handleQuery() przycisku onclick 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 czyści wszystkie szczegółowe informacje 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 adres URL punktu końcowego, ustawia Ocp-Apim-Subscription-Key nagłówek na klucz subskrypcji, dołącza plik binarny obrazu do przekazania, 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, analizuje odpowiedź JSON, wprowadzając ją do poszczególnych tagów ze szczegółowymi informacjami. 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() wykonuje iterację po przeanalizowanych tagach JSON i wywołuje buildDiv() funkcję w celu utworzenia <div> elementu 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 addDivContent funkcję w celu skompilowania zawartości zwijanego <div>tagu .

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 w witrynie Bing.com albo w pierwotnej witrynie internetowej obrazu. W tej aplikacji nie są wyświetlane wszystkie dane ze szczegółowych informacji. Aby wyświetlić wszystkie pola dostępne dla szczegółowych informacji, zobacz dokumentację 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.

Szczegółowe informacje dotyczące akcji RelatedImages

Funkcja addRelatedImages() tworzy tytuł dla każdej z witryn internetowych hostujących powiązany obraz, iterując przez listę RelatedImages akcji i dołączając <img> tag na zewnątrz <div> dla każdego z nich:

    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 informacje dotyczące akcji PagesIncluding

Funkcja addPagesIncluding() tworzy link dla każdej z witryn internetowych hostujących przekazany obraz, iterując przez listę PagesIncluding akcji i dołączając <img> tag na zewnątrz <div> dla każdego 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'));
        }
    }

Szczegółowe informacje dotyczące akcji 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);

        }
    }

Szczegółowe informacje dotyczące przepisów

Funkcja addRecipes() tworzy link dla każdego z przepisów zwracanych przez iterację po liście Recipes akcji i dołączanie <img> tagu 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 wszystkich zwróconych wyników zakupów, iterując przez listę RelatedImages akcji i dołączając <img> tag na zewnątrz <div> dla każdego z nich:

    // 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 wszystkich zwróconych produktów, iterując listę Products akcji i dołączając <img> tag 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);
                }
            }
        }
    }

Szczegółowe informacje dotyczące akcji 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 umożliwiający użytkownikowi Bing.com, gdzie może uzyskać szczegółowe informacje o typie jednostki na obrazie, jeśli 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 obraz możliwy do kliknięcia, który <div> powoduje przejście użytkownika do wyników wyszukiwania w 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