Chiama il backend dell'API Vision Product Search su Android

1. Prima di iniziare

bd8c01b2f8013c6d.png

Hai visto la demo di Google Lens, in cui puoi puntare la fotocamera dello smartphone verso un oggetto e scoprire dove puoi acquistarlo online? Se vuoi scoprire come aggiungere la stessa funzionalità alla tua app, questo codelab fa al caso tuo. Fa parte di un percorso di apprendimento che ti insegna come integrare una funzionalità di ricerca di immagini di prodotti in un'app mobile.

In questo codelab, imparerai a chiamare un backend creato con Product Search dell'API Vision da un'app mobile. Questo backend può prendere un'immagine di query e cercare prodotti visivamente simili da un catalogo prodotti.

Puoi scoprire i passaggi rimanenti per creare una funzionalità di ricerca visiva dei prodotti, incluso come utilizzare ML Kit Object Detection and Tracking per rilevare gli oggetti nell'immagine della query e consentire agli utenti di scegliere il prodotto che vogliono cercare, nel percorso di apprendimento.

Cosa creerai

  • In questo codelab, inizierai con l'app per Android in grado di rilevare oggetti da un'immagine di input. Scriverai il codice per prendere l'oggetto scelto dall'utente, inviarlo al backend di ricerca dei prodotti e visualizzare il risultato della ricerca sullo schermo.
  • Alla fine, dovresti vedere qualcosa di simile all'immagine a destra.

Cosa imparerai a fare

  • Come chiamare e analizzare la risposta delle API Vision Product Search da un'app per Android

Che cosa ti serve

  • Una versione recente di Android Studio (v4.1.2 o versioni successive)
  • Emulatore Android Studio o un dispositivo Android fisico
  • Il codice campione
  • Conoscenza di base dello sviluppo Android in Kotlin

Questo codelab è incentrato su Vision API Product Search. Concetti e blocchi di codice non pertinenti non vengono esplorati e sono forniti solo per operazioni di copia e incolla.

2. Informazioni su Vision API Product Search

Product Search dell'API Vision è una funzionalità di Google Cloud che consente agli utenti di cercare prodotti visivamente simili in un catalogo di prodotti. I rivenditori possono creare prodotti, ciascuno contenente immagini di riferimento che descrivono visivamente il prodotto da un insieme di punti di vista. Puoi quindi aggiungere questi prodotti ai gruppi di prodotti (ovvero al catalogo prodotti). Al momento, Vision API Product Search supporta le seguenti categorie di prodotti: articoli per la casa, abbigliamento, giocattoli, confezionati e in generale.

Quando gli utenti eseguono query sul set di prodotti con le proprie immagini, Product Search dell'API Vision applica il machine learning per confrontare il prodotto nell'immagine della query dell'utente con le immagini del set di prodotti del rivenditore, poi restituisce un elenco classificato di risultati simili a livello visivo e semantico.

3. Scaricare ed eseguire l'app iniziale

Scarica il codice

Fai clic sul seguente link per scaricare tutto il codice per questo codelab:

Decomprimi il file ZIP scaricato. Verrà estratta una cartella principale (odml-pathways-main) con tutte le risorse necessarie. Per questo codelab, ti serviranno solo le origini nella sottodirectory product-search/codelab2/android.

La sottodirectory codelab2 nel repository odml-pathways contiene due directory:

  • android_studio_folder.pngstarter: il codice iniziale su cui si basa questo codelab.
  • android_studio_folder.pngfinal: codice completato per l'app di esempio finita.

L'app iniziale qui è quella che hai creato nel codelab Rilevare oggetti nelle immagini per creare una ricerca visiva di prodotti: Android. Utilizza ML Kit Object Detection and Tracking per rilevare gli oggetti da un'immagine e mostrarli sullo schermo.

Importare l'app in Android Studio

Inizia importando l'app starter in Android Studio.

Vai ad Android Studio, seleziona Import Project (Gradle, Eclipse ADT, etc.) e scegli la cartella starter dal codice sorgente che hai scaricato in precedenza.

7c0f27882a2698ac.png

Eseguire l'app iniziale

Ora che hai importato il progetto in Android Studio, puoi eseguire l'app per la prima volta. Collega il dispositivo Android tramite USB all'host o avvia l'emulatore Android Studio e fai clic su Esegui ( execute.png) nella barra degli strumenti di Android Studio.

Se questo pulsante è disattivato, assicurati di importare solo starter/app/build.gradle e non l'intero repository.

Ora l'app dovrebbe essere stata avviata sul tuo dispositivo Android. Ha già la funzionalità di rilevamento degli oggetti: rileva gli articoli di moda dall'immagine e ti mostra dove si trovano. Prova con le foto preimpostate per confermare.

c6102a808fdfcb11.png

Screenshot dell'app iniziale in grado di rilevare oggetti in un'immagine

Successivamente, estenderai l'app per inviare gli oggetti rilevati al backend dell'API Vision Product Search e mostrare i risultati della ricerca sullo schermo.

4. Gestire la selezione degli oggetti

Consenti agli utenti di toccare un oggetto rilevato per selezionarlo

Ora aggiungerai il codice per consentire agli utenti di selezionare un oggetto dall'immagine e avviare la ricerca del prodotto. L'app iniziale ha già la capacità di rilevare gli oggetti nell'immagine. È possibile che nell'immagine siano presenti più oggetti o che l'oggetto rilevato occupi solo una piccola parte dell'immagine. Pertanto, l'utente deve toccare uno degli oggetti rilevati per indicare quale vuole utilizzare per la ricerca di prodotti.

9cdfcead6d95a87.png

Uno screenshot degli articoli di moda rilevati dall'immagine

Per mantenere il codelab semplice e incentrato sul machine learning, nell'app iniziale è stato implementato del codice Android boilerplate per aiutarti a rilevare l'oggetto su cui l'utente ha toccato. La visualizzazione che mostra l'immagine nell'attività principale (ObjectDetectorActivity) è in realtà una visualizzazione personalizzata (ImageClickableView) che estende ImageView predefinito del sistema operativo Android. Implementa alcuni metodi di utilità pratici, tra cui:

  • fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit)) Questo è un callback per ricevere l'immagine ritagliata che contiene solo l'oggetto su cui l'utente ha toccato. Invierai questa immagine ritagliata al backend della ricerca dei prodotti.

Aggiungi codice per gestire il tocco degli oggetti rilevati da parte dell'utente.

Vai al metodo initViews nella classe ObjectDetectorActivity e aggiungi queste righe alla fine del metodo: (Android Studio ti comunicherà che non riesce a trovare il metodo startProductImageSearch . Non preoccuparti, lo implementerai un po' più tardi.)

// Callback received when the user taps on any of the detected objects.
ivPreview.setOnObjectClickListener { objectImage ->
    startProductImageSearch(objectImage)
}

onObjectClickListener viene chiamato ogni volta che l'utente tocca uno degli oggetti rilevati sullo schermo. Riceve l'immagine ritagliata che contiene solo l'oggetto selezionato. Ad esempio, se l'utente tocca la persona che indossa l'abito a destra, l'intent viene attivato con objectImage come mostrato di seguito.

9cac8458d0f326e6.png

Un esempio dell'immagine ritagliata passata a onObjectClickListener

Inviare l'immagine ritagliata all'attività di ricerca prodotto

Ora implementerai la logica di invio dell'immagine della query al backend di Vision API Product Search in un'attività separata (ProductSearchActivity).

Tutti i componenti della UI sono stati implementati in anticipo, così puoi concentrarti sulla scrittura del codice per comunicare con il backend di ricerca dei prodotti.

25939f5a13eeb3c3.png

Uno screenshot dei componenti dell'interfaccia utente in ProductSearchActivity

Aggiungi il codice per inviare l'immagine dell'oggetto selezionato dall'utente a ProductSearchActivity.

Torna ad Android Studio e aggiungi questo metodo startProductImageSearch alla classe ObjectDetectorActivity:

private fun startProductImageSearch(objectImage: Bitmap) {
    try {
        // Create file based Bitmap. We use PNG to preserve the image quality
        val savedFile = createImageFile(ProductSearchActivity.CROPPED_IMAGE_FILE_NAME)
        objectImage.compress(Bitmap.CompressFormat.PNG, 100, FileOutputStream(savedFile))

        // Start the product search activity (using Vision Product Search API.).
        startActivity(
            Intent(
                    this,
                    ProductSearchActivity::class.java
            ).apply {
                // As the size limit of a bundle is 1MB, we need to save the bitmap to a file
                // and reload it in the other activity to support large query images.
                putExtra(
                    ProductSearchActivity.REQUEST_TARGET_IMAGE_PATH,
                    savedFile.absolutePath
                )
            })
    } catch (e: Exception) {
        // IO Exception, Out Of memory ....
        Toast.makeText(this, e.message, Toast.LENGTH_SHORT).show()
        Log.e(TAG, "Error starting the product image search activity.", e)
    }
}

Lo snippet di codice esegue tre operazioni:

  • Prende l'immagine ritagliata e la serializza in un file PNG.
  • Avvia ProductSearchActivity per eseguire la sequenza di ricerca del prodotto.
  • Include l'URI dell'immagine ritagliata nell'intent di avvio dell'attività in modo che ProductSearchActivity possa recuperarlo in un secondo momento per utilizzarlo come immagine della query.

Tieni in considerazione alcuni aspetti:

  • La logica per il rilevamento degli oggetti e l'interrogazione del backend è stata suddivisa in due attività solo per semplificare la comprensione del codelab. Spetta a te decidere come implementarle nella tua app.
  • Devi scrivere l'immagine di query in un file e passare l'URI dell'immagine tra le attività perché l'immagine di query può superare il limite di dimensioni di 1 MB di un intent Android.
  • Puoi archiviare l'immagine della query in formato PNG perché è un formato senza perdita.

Recupera l'immagine della query nell'attività di ricerca di prodotti

In ProductSearchActivity, il codice per recuperare l'immagine della query e visualizzarla sullo schermo è già stato implementato nell'app iniziale.

Vai al metodo onCreate e verifica che questo codice sia già presente:

// Receive the query image and show it on the screen
intent.getStringExtra(REQUEST_TARGET_IMAGE_PATH)?.let { absolutePath ->
    viewBinding.ivQueryImage.setImageBitmap(BitmapFactory.decodeFile(absolutePath))
}

Esegui l'app

Ora fai clic su Esegui ( execute.png) nella barra degli strumenti di Android Studio.

Una volta caricata l'app, tocca una delle immagini preimpostate e seleziona uno degli oggetti rilevati.

Verifica che ProductSearchActivity venga visualizzato con l'immagine che hai toccato. Il pulsante Cerca non fa ancora nulla, ma lo implementeremo in futuro.

fed40f81b8b43801.png

Dopo aver toccato uno degli oggetti rilevati, dovresti visualizzare una schermata simile.

5. Esplorare il backend della ricerca dei prodotti

Creare il backend per la ricerca di immagini di prodotti

Questo codelab richiede un backend di ricerca dei prodotti creato con Product Search dell'API Vision. Per farlo, hai due opzioni:

Opzione 1: utilizza il backend demo che è stato implementato per te

Puoi procedere con questo codelab utilizzando il backend di ricerca dei prodotti che Google ha già implementato per te. Il backend demo può essere replicato seguendo la guida rapida di Vision API Product Search.

Opzione 2: crea il tuo backend seguendo la guida rapida di Vision API Product Search

Questa opzione è consigliata a chi vuole imparare in modo approfondito a creare un backend di ricerca dei prodotti per poterlo creare in un secondo momento per il proprio catalogo di prodotti. È necessario disporre di:

  • Un account Google Cloud con la fatturazione attivata. Può trattarsi di un account di prova senza costi.
  • Alcune conoscenze sui concetti di Google Cloud, tra cui progetti, service account e così via.

Puoi scoprire come farlo più avanti nel percorso di apprendimento.

Scopri i concetti importanti

Quando interagisci con il backend della ricerca di prodotti, incontrerai questi concetti:

  • Set di prodotti: un set di prodotti è un semplice contenitore per un gruppo di prodotti. Un catalogo dei prodotti può essere rappresentato come un insieme di prodotti e i relativi prodotti.
  • Prodotto: dopo aver creato un set di prodotti, puoi creare prodotti e aggiungerli al set.
  • Immagini di riferimento del prodotto: sono immagini che contengono varie visualizzazioni dei tuoi prodotti. Le immagini di riferimento vengono utilizzate per cercare prodotti visivamente simili.
  • Cerca prodotti: dopo aver creato il set di prodotti e dopo che è stato indicizzato, puoi eseguire query sul set di prodotti utilizzando l'API Cloud Vision.

Informazioni sul catalogo dei prodotti preimpostato

Il backend della demo di ricerca di prodotti utilizzato in questo codelab è stato creato utilizzando l'API Vision Product Search e un catalogo di prodotti di circa cento immagini di scarpe e vestiti. Ecco alcune immagini del catalogo:

4f1a8507b74ab178.png 79a5fc6c829eca77.png 3528c872f813826e.png

Esempi dal catalogo dei prodotti preimpostato

Chiama il backend della demo di ricerca dei prodotti

Puoi chiamare l'API Cloud Vision Product Search direttamente da un'app mobile configurando una chiave API Google Cloud e limitando l'accesso alla chiave API solo alla tua app.

Per semplificare questo codelab, è stato configurato un endpoint proxy che consente di accedere al backend demo senza preoccuparsi della chiave API e dell'autenticazione. Riceve la richiesta HTTP dall'app mobile, aggiunge la chiave API e inoltra la richiesta al backend di Product Search dell'API Vision. Il proxy riceve quindi la risposta dal backend e la restituisce all'app mobile.

In questo codelab utilizzerai due API di Vision API Product Search:

6. Implementa il client API

Informazioni sul flusso di lavoro di ricerca dei prodotti

Segui questo flusso di lavoro per eseguire la ricerca di prodotti con il backend:

Implementare la classe client API

Ora implementerai il codice per chiamare il backend di ricerca dei prodotti in una classe dedicata chiamata ProductSearchAPIClient. Nell'app iniziale è stato implementato del codice boilerplate:

  • class ProductSearchAPIClient: questa classe è quasi vuota, ma contiene alcuni metodi che implementerai più avanti in questo codelab.
  • fun convertBitmapToBase64(bitmap: Bitmap): Converti un'istanza Bitmap nella relativa rappresentazione Base64 da inviare al backend di ricerca dei prodotti
  • fun annotateImage(image: Bitmap): Task<List<ProductSearchResult>>: chiama l'API projects.locations.images.annotate e analizza la risposta.
  • fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult>: chiama l'API projects.locations.products.referenceImages.get e analizza la risposta.
  • SearchResult.kt: questo file contiene diverse classi di dati per rappresentare i tipi restituiti dal backend di Vision API Product Search.

Specificare le configurazioni API

Vai alla classe ProductSearchAPIClient e vedrai alcune configurazioni del backend di ricerca dei prodotti già definite:

// Define the product search backend
// Option 1: Use the demo project that we have already deployed for you
const val VISION_API_URL =
    "https://us-central1-odml-codelabs.cloudfunctions.net/productSearch"
const val VISION_API_KEY = ""
const val VISION_API_PROJECT_ID = "odml-codelabs"
const val VISION_API_LOCATION_ID = "us-east1"
const val VISION_API_PRODUCT_SET_ID = "product_set0"
  • VISION_API_URL è l'endpoint API dell'API Cloud Vision. Man mano che procedi con il backend demo, impostalo sull'endpoint proxy. Tuttavia, se esegui il deployment del tuo backend, dovrai modificarlo con l'endpoint dell'API Cloud Vision. https://vision.googleapis.com/v1.
  • VISION_API_KEY è la chiave API del tuo progetto Cloud. Poiché il proxy gestisce già l'autenticazione, puoi lasciare vuoto questo campo.
  • VISION_API_PROJECT_ID è l'ID progetto Cloud. odml-codelabs è il progetto Cloud in cui viene eseguito il deployment del backend demo.
  • VISION_API_LOCATION_ID è la località cloud in cui viene implementato il backend di ricerca dei prodotti. us-east1 è la posizione in cui abbiamo eseguito il deployment del backend demo.
  • VISION_API_PRODUCT_SET_ID è l'ID del catalogo dei prodotti (ovvero "set di prodotti" nel termine dell'API Vision) in cui vuoi cercare prodotti visivamente simili. Puoi avere più cataloghi in un progetto Cloud. product_set0 è il catalogo dei prodotti preimpostato del backend demo.

7. Chiama l'API Product Search

Esplora il formato di richiesta e risposta dell'API

Puoi trovare prodotti simili a una determinata immagine trasmettendo l'URI Google Cloud Storage, l'URL web o la stringa codificata Base64 dell'immagine a Product Search dell'API Vision. In questo codelab, utilizzerai l'opzione della stringa codificata in base64, poiché la nostra immagine di query esiste solo nel dispositivo dell'utente.

Devi inviare una richiesta POST all'endpoint projects.locations.images.annotate con questo corpo JSON della richiesta:

{
  "requests": [
    {
      "image": {
        "content": {base64-encoded-image}
      },
      "features": [
        {
          "type": "PRODUCT_SEARCH",
          "maxResults": 5
        }
      ],
      "imageContext": {
        "productSearchParams": {
          "productSet": "projects/{project-id}/locations/{location-id}/productSets/{product-set-id}",
          "productCategories": [
               "apparel-v2"
          ],
        }
      }
    }
  ]
}

Esistono alcuni parametri che devono essere specificati:

  • base64-encoded-image: la rappresentazione Base64 (stringa ASCII) dei dati binari dell'immagine della query.
  • project-id: il tuo ID progetto Google Cloud.
  • location-id: un identificatore di località valido.
  • product-set-id: l'ID del set di prodotti su cui vuoi eseguire l'operazione.

Poiché il tuo catalogo di prodotti contiene solo immagini di scarpe e abiti, specifica che productCategories è apparel-v2. v2 indica che utilizziamo la versione 2 del modello di machine learning per la ricerca di prodotti di abbigliamento.

Se la richiesta riesce, il server restituisce un codice di stato HTTP 200 OK e la risposta in formato JSON. Il JSON di risposta include i due seguenti tipi di risultati:

  • productSearchResults: contiene un elenco di prodotti corrispondenti per l'intera immagine.
  • productGroupedResults: contiene le coordinate del riquadro di delimitazione e gli articoli corrispondenti per ogni prodotto identificato nell'immagine.

Poiché il prodotto è già stato ritagliato dall'immagine originale, analizzerai i risultati nell'elenco productSearchResults.

Di seguito sono riportati alcuni campi importanti nell'oggetto risultato di ricerca del prodotto:

  • product.name: l'identificatore univoco di un prodotto nel formato projects/{project-id}/locations/{location-id}/products/{product_id}
  • product.score: un valore che indica il grado di somiglianza del risultato di ricerca con l'immagine della query. Valori più alti indicano una maggiore somiglianza.
  • product.image: l'identificatore univoco dell'immagine di riferimento di un prodotto nel formato projects/{project-id}/locations/{location-id}/products/{product_id}/referenceImages/{image_id}. Dovrai inviare un'altra richiesta API a projects.locations.products.referenceImages.get per ottenere l'URL di questa immagine di riferimento in modo che venga visualizzata sullo schermo.
  • product.labels: un elenco di tag predefiniti del prodotto. Questa opzione è utile se vuoi filtrare i risultati di ricerca in modo da visualizzare solo una categoria di abbigliamento, ad esempio gli abiti.

Convertire l'immagine della query in base64

Devi convertire l'immagine di query nella relativa rappresentazione di stringa base64 e allegare la stringa all'oggetto JSON nel corpo della richiesta.

Vai alla classe ProductSearchAPIClient, trova il metodo convertBitmapToBase64 vuoto e sostituiscilo con questa implementazione:

private fun convertBitmapToBase64(bitmap: Bitmap): String {
    val byteArrayOutputStream = ByteArrayOutputStream()
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)
    val byteArray: ByteArray = byteArrayOutputStream.toByteArray()
    return Base64.encodeToString(byteArray, Base64.DEFAULT)
}

Implementa la chiamata API

Poi, crea una richiesta API Product Search e inviala al backend. Utilizzerai Volley per effettuare la richiesta API e restituire il risultato utilizzando l'API Task.

Torna alla classe ProductSearchAPIClient, trova il metodo annotateImage vuoto e sostituiscilo con questa implementazione:

fun annotateImage(image: Bitmap): Task<List<ProductSearchResult>> {
    // Initialization to use the Task API
    val apiSource = TaskCompletionSource<List<ProductSearchResult>>()
    val apiTask = apiSource.task

    // Convert the query image to its Base64 representation to call the Product Search API.
    val base64: String = convertBitmapToBase64(image)

    // Craft the request body JSON.
    val requestJson = """
        {
          "requests": [
            {
              "image": {
                "content": """".trimIndent() + base64 + """"
              },
              "features": [
                {
                  "type": "PRODUCT_SEARCH",
                  "maxResults": $VISION_API_PRODUCT_MAX_RESULT
                }
              ],
              "imageContext": {
                "productSearchParams": {
                  "productSet": "projects/${VISION_API_PROJECT_ID}/locations/${VISION_API_LOCATION_ID}/productSets/${VISION_API_PRODUCT_SET_ID}",
                  "productCategories": [
                       "apparel-v2"
                     ]
                }
              }
            }
          ]
        }
    """.trimIndent()

    // Add a new request to the queue
    requestQueue.add(object :
        JsonObjectRequest(
            Method.POST,
            "$VISION_API_URL/images:annotate?key=$VISION_API_KEY",
            JSONObject(requestJson),
            { response ->
                // Parse the API JSON response to a list of ProductSearchResult object/
                val productList = apiResponseToObject(response)

                // Return the list.
                apiSource.setResult(productList)
            },
            // Return the error
            { error -> apiSource.setException(error) }
        ) {
        override fun getBodyContentType() = "application/json"
    }.apply {
        setShouldCache(false)
    })

    return apiTask
}

Mostrare il risultato di ricerca nell'interfaccia utente

Ora il codice API in ProductSearchAPIClient è pronto. Torna all'attività ProductSearchActivity per implementare il codice dell'interfaccia utente.

L'attività ha già del codice boilerplate che attiva il metodo searchByImage(queryImage: Bitmap). Aggiungi codice per chiamare il backend e mostrare i risultati nell'interfaccia utente in questo metodo attualmente vuoto.

apiClient.annotateImage(queryImage)
    .addOnSuccessListener { showSearchResult(it) }
    .addOnFailureListener { error ->
        Log.e(TAG, "Error calling Vision API Product Search.", error)
        showErrorResponse(error.localizedMessage)
    }

Il metodo showSearchResult contiene del codice standard che analizza la risposta dell'API e la mostra sullo schermo.

Run it

Ora fai clic su Esegui ( execute.png) nella barra degli strumenti di Android Studio. Una volta caricata l'app, tocca una delle immagini preimpostate, seleziona un oggetto rilevato, tocca il pulsante Cerca e visualizza i risultati di ricerca restituiti dal backend. Visualizzerai un riquadro simile al seguente:

bb5e7c27c283a2fe.png

Screenshot della schermata dei risultati di ricerca del prodotto

Il backend restituisce già un elenco di prodotti visivamente simili dal catalogo prodotti preimpostato. Tuttavia, puoi notare che l'immagine del prodotto è ancora vuota. Questo perché l'endpoint projects.locations.images.annotate restituisce solo gli ID immagine prodotto come projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77. Dovrai effettuare un'altra chiamata API all'endpoint projects.locations.products.referenceImages.get e ottenere l'URL di questa immagine di riferimento per visualizzarla sullo schermo.

8. Ottenere le immagini di riferimento del prodotto

Esplora il formato di richiesta e risposta dell'API

Invia una richiesta GET HTTP con un corpo della richiesta vuoto all'endpoint projects.locations.products.referenceImages.get per ottenere gli URI delle immagini del prodotto restituite dall'endpoint di ricerca dei prodotti.

La richiesta HTTP è simile a questa:

GET $VISION_API_URL/projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77?key=$VISION_API_KEY

Se la richiesta riesce, il server restituisce un codice di stato HTTP 200 OK e la risposta in formato JSON come di seguito:

{
  "name":"projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77",
  "uri":"gs://cloud-ai-vision-data/product-search-tutorial/images/46991e7370ba11e8a1bbd20059124800.jpg"
}
  • name: l'identificatore dell'immagine di riferimento.
  • uri: l'URI dell'immagine su Google Cloud Storage (GCS).

Le immagini di riferimento del backend di ricerca dei prodotti demo sono state configurate in modo da disporre dell'autorizzazione di lettura pubblica. Pertanto, puoi convertire facilmente l'URI GCS in un URL HTTP e visualizzarlo nell'interfaccia utente dell'app. Devi solo sostituire il prefisso gs:// con https://storage.googleapis.com/.

Implementa la chiamata API

Poi, crea una richiesta API Product Search e inviala al backend. Utilizzerai Volley e l'API Task in modo simile alla chiamata API Product Search.

Torna alla classe ProductSearchAPIClient, trova il metodo fetchReferenceImage vuoto e sostituiscilo con questa implementazione:

private fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult> {
    // Initialization to use the Task API
    val apiSource = TaskCompletionSource<ProductSearchResult>()
    val apiTask = apiSource.task

    // Craft the API request to get details about the reference image of the product
    val stringRequest = object : StringRequest(
        Method.GET,
        "$VISION_API_URL/${searchResult.imageId}?key=$VISION_API_KEY",
        { response ->
            val responseJson = JSONObject(response)
            val gcsUri = responseJson.getString("uri")

            // Convert the GCS URL to its HTTPS representation
            val httpUri = gcsUri.replace("gs://", "https://storage.googleapis.com/")

            // Save the HTTPS URL to the search result object
            searchResult.imageUri = httpUri

            // Invoke the listener to continue with processing the API response (eg. show on UI)
            apiSource.setResult(searchResult)
        },
        { error -> apiSource.setException(error) }
    ) {

        override fun getBodyContentType(): String {
            return "application/json; charset=utf-8"
        }
    }
    Log.d(ProductSearchActivity.TAG, "Sending API request.")

    // Add the request to the RequestQueue.
    requestQueue.add(stringRequest)

    return apiTask
}

Questo metodo accetta un oggetto searchResult: ProductSearchResult restituito dall'endpoint di ricerca dei prodotti e segue questi passaggi:

  1. Chiama l'endpoint dell'immagine di riferimento per ottenere l'URI GCS dell'immagine di riferimento.
  2. Converte l'URI GCS in un URL HTTP.
  3. Aggiorna la proprietà httpUri dell'oggetto searchResult con questo URL HTTP.

Collega le due richieste API

Torna a annotateImage e modificalo per ottenere tutti gli URL HTTP delle immagini di riferimento prima di restituire l'elenco ProductSearchResult al chiamante.

Trova questa riga:

// Return the list.
apiSource.setResult(productList)

Quindi sostituiscilo con questa implementazione:

// Loop through the product list and create tasks to load reference images.
// We will call the projects.locations.products.referenceImages.get endpoint
// for each product.
val fetchReferenceImageTasks = productList.map { fetchReferenceImage(it) }

// When all reference image fetches have completed,
// return the ProductSearchResult list
Tasks.whenAllComplete(fetchReferenceImageTasks)
    // Return the list of ProductSearchResult with product images' HTTP URLs.
    .addOnSuccessListener { apiSource.setResult(productList) }
    // An error occurred so returns it to the caller.
    .addOnFailureListener { apiSource.setException(it) }

Il codice boilerplate per visualizzare le immagini di riferimento sullo schermo è già implementato nella classe ProductSearchAdapter, quindi puoi procedere con la riesecuzione dell'app.

Run it

Ora fai clic su Esegui ( execute.png) nella barra degli strumenti di Android Studio. Una volta caricata l'app, tocca una delle immagini preimpostate, seleziona un oggetto rilevato e tocca il pulsante Cerca per visualizzare i risultati di ricerca, questa volta con le immagini del prodotto.

I risultati della ricerca di prodotti ti sembrano pertinenti?

25939f5a13eeb3c3.png

9. Complimenti!

Hai imparato a chiamare un backend dell'API Vision Product Search per aggiungere la funzionalità di ricerca di immagini di prodotti alla tua app per Android. Questo è tutto ciò che ti serve per iniziare.

Man mano che procedi, potresti voler creare il tuo backend utilizzando il catalogo prodotti. Consulta il codelab successivo nel percorso di apprendimento Ricerca di immagini di prodotti per scoprire come creare il tuo backend e configurare la chiave API per chiamarlo da un'app mobile.

Argomenti trattati

  • Come chiamare il backend dell'API Vision Product Search da un'app per Android

Passaggi successivi

Scopri di più