Back-end da Pesquisa de produtos da API Vision no Android

1. Antes de começar

bd8c01b2f8013c6d.png

Já viu a demonstração do Google Lens, onde você pode apontar a câmera do smartphone para um objeto e descobrir onde pode comprá-lo on-line? Se você quer saber como adicionar o mesmo recurso ao app, este codelab é ideal. Ele faz parte de um programa de aprendizado que ensina a criar um recurso de pesquisa de imagens de produtos em um app para dispositivos móveis.

Neste codelab, você aprenderá a chamar um back-end criado com a Pesquisa de produtos da API Vision de um app para dispositivos móveis. Esse back-end pode usar uma imagem de consulta e pesquisar produtos visualmente semelhantes a partir de um catálogo de produtos.

Saiba mais sobre as outras etapas da criação de um recurso de pesquisa visual de produtos, incluindo como usar a detecção e o rastreamento de objetos do ML Kit para detectar objetos na imagem de consulta e permitir que os usuários escolham o produto que querem pesquisar. , no programa de aprendizado.

O que você criará

  • Neste codelab, você começará usando o app Android que pode detectar objetos de uma imagem de entrada. Você escreverá o código para selecionar o objeto escolhido pelo usuário, enviá-lo ao back-end de pesquisa de produtos e exibir o resultado da pesquisa na tela.
  • No final, você verá algo semelhante à imagem à direita.

O que você aprenderá

  • Como chamar e analisar a resposta das APIs da Pesquisa de produtos da API Vision de um app Android

Pré-requisitos

  • Uma versão recente do Android Studio (v4.1.2 ou mais recente)
  • Android Studio Emulator ou um dispositivo Android físico
  • Código de amostra
  • Conhecimento básico de desenvolvimento Android no Kotlin.

Este codelab é focado na Pesquisa de produtos da API Vision. Conceitos não-relevantes e blocos de código não são explorados e são fornecidos para que você apenas os copie e cole.

2. Sobre a Pesquisa de produtos da API Vision

A Pesquisa de produtos da API Vision é um recurso do Google Cloud que permite pesquisar produtos visualmente semelhantes em um catálogo de produtos. Os varejistas podem criar produtos, cada um contendo imagens de referência que descrevem visualmente o produto com base em um conjunto de pontos de vista. Em seguida, você pode adicionar esses itens aos conjuntos (por exemplo, catálogo de produtos). Atualmente, a Pesquisa de produtos da API Vision é compatível com as seguintes categorias de produtos: artigos domésticos, vestuário, brinquedos, produtos embalados e produtos em geral.

Quando os usuários consultam o conjunto de produtos com as próprias imagens, a Pesquisa de produtos da API Vision aplica o aprendizado de máquina para comparar o produto na imagem de consulta do usuário com as imagens no conjunto de produtos do varejista. Em seguida, ela retorna uma lista classificada de resultados visualmente e semânticos semelhantes.

3. Fazer o download e executar o app inicial

Fazer o download do código

Clique no link abaixo para fazer o download de todo o código para este codelab:

Descompacte o arquivo ZIP transferido por download. Isso descompactará uma pasta raiz (odml-pathways-main) com todos os recursos necessários. Neste codelab, você só precisará das origens no subdiretório product-search/codelab2/android.

O subdiretório codelab2 no repositório odml-pathways contém dois diretórios:

  • android_studio_folder.pngstarter: o código inicial que você usará como base para este codelab.
  • android_studio_folder.pngfinal: o código concluído do app de exemplo finalizado.

O app inicial aqui é aquele que você criou no codelab Detectar objetos em imagens para criar uma pesquisa visual de produto: Android. Ele usa a detecção e o rastreamento de objetos do ML Kit para detectar objetos de uma imagem e exibi-los na tela.

Importar o app para o Android Studio

Para começar, importe o app starter para o Android Studio.

Acesse o Android Studio, selecione Import Project (Gradle, Eclipse ADT, etc.) e escolha a pasta starter no código-fonte que você já baixou.

7c0f27882a2698ac.png

Executar o app inicial

Agora que você importou o projeto para o Android Studio, está pronto para executar o app pela primeira vez. Conecte o dispositivo Android via USB ao seu host ou Iniciar o Android Studio e clique em Run ( execute.png) na barra de ferramentas do Android Studio.

Se esse botão estiver desativado, importe apenas o inicializador/app/build.gradle, e não todo o repositório.

Agora, o app deve ter sido aberto no seu dispositivo Android. Ela já tem o recurso de detecção de objetos: detectar itens de moda da imagem e mostrar onde eles estão. Tente usar as fotos predefinidas para confirmar.

c6102a808fdfcb11.png

Captura de tela do app inicial que pode detectar objetos em uma imagem

Em seguida, estenda o app para enviar os objetos detectados ao back-end da Pesquisa de produtos da API Vision e mostrar os resultados da pesquisa na tela.

4. Processar a seleção de objetos

Permitir que os usuários toquem em um objeto detectado para selecionar

Agora você adicionará um código para permitir que os usuários selecionem um objeto na imagem e iniciem a pesquisa de produtos. O app inicial já pode detectar objetos na imagem. É possível que haja vários objetos na imagem, ou que o objeto detectado ocupe apenas uma pequena parte da imagem. Por isso, o usuário precisa tocar em um dos objetos detectados para indicar qual ele quer usar na pesquisa de produtos.

9cdfcead6d95a87.png

Captura de tela dos itens de moda detectados na imagem

Para simplificar o codelab e se concentrar no aprendizado de máquina, um código Android padrão foi implementado no app inicial para ajudar a detectar em qual objeto o usuário tocou. A visualização que exibe a imagem na atividade principal (ObjectDetectorActivity) é, na verdade, uma visualização personalizada (ImageClickableView) que estende o ImageView padrão do SO Android. Ela implementa alguns métodos utilitários convenientes, incluindo:

  • fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit)): é um callback para receber a imagem cortada que contém apenas o objeto em que o usuário tocou. Você enviará essa imagem cortada para o back-end da Pesquisa de produtos.

Adicione um código para processar um usuário que toca nos objetos detectados.

Acesse o método initViews na classe ObjectDetectorActivity e adicione estas linhas no final do método: (o Android Studio dirá que não consegue encontrar o startProductImageSearch . Não se preocupe, isso será implementado um pouco mais tarde.

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

O onObjectClickListener é chamado sempre que o usuário toca em qualquer um dos objetos detectados na tela. Ela recebe a imagem cortada que contém apenas o objeto selecionado. Por exemplo, se o usuário tocar na pessoa usando o vestido à direita, o listener será acionado com a objectImage, conforme mostrado abaixo.

9cac8458d0f326e6.png

Um exemplo da imagem cortada transmitida para o onObjectClickListener

Enviar a imagem cortada para a atividade de pesquisa do produto

Agora, implemente a lógica de envio da imagem da consulta ao back-end da Pesquisa de produtos da API Vision em uma atividade separada (ProductSearchActivity).

Todos os componentes da IU foram implementados com antecedência para que você possa se concentrar em escrever o código para se comunicar com o back-end da Pesquisa de produtos.

25939f5a13eeb3c3.png

Captura de tela dos componentes da IU em ProductSearchActivity

Adicione um código para enviar a imagem do objeto selecionada ao ProductSearchActivity.

Volte para o Android Studio e adicione este método startProductImageSearch à 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)
    }
}

O snippet de código faz três coisas:

  • Recebe a imagem cortada e a serializa em um arquivo PNG.
  • Inicia o ProductSearchActivity para executar a sequência de pesquisa de produtos.
  • Inclui o URI da imagem cortada na intent de atividade inicial para que ProductSearchActivity possa recuperá-lo mais tarde e usá-lo como imagem de consulta.

É importante ter algumas dicas importantes em mente:

  • A lógica para detectar objetos e consultar o back-end foi dividida em duas atividades apenas para facilitar o entendimento do codelab. Cabe a você decidir como implementá-las no seu app.
  • Você precisa gravar a imagem da consulta em um arquivo e transmitir o URI da imagem entre as atividades, porque a imagem pode ser maior que o limite de 1 MB do tamanho de uma intent do Android.
  • Você pode armazenar a imagem de consulta em PNG porque ela é um formato sem perdas.

Recuperar a imagem de consulta na atividade de pesquisa do produto

No ProductSearchActivity, o código para recuperar a imagem da consulta e exibi-la na tela já foi implementado no app inicial.

Acesse o método onCreate e confirme se este código já está lá:

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

Executar o app

Agora, clique em Run ( execute.png) na barra de ferramentas do Android Studio.

Depois que o app for carregado, toque em qualquer imagem predefinida e selecione um dos objetos detectados.

Confirme se o ProductSearchActivity é exibido com a imagem que você tocou. O botão Pesquisar ainda não faz nada, mas será implementado a seguir.

fed40f81b8b43801.png

Você verá uma tela semelhante ao tocar em um dos objetos detectados.

5. Explore o back-end da pesquisa de produto

Criar o back-end de pesquisa da imagem do produto

Este codelab requer um back-end de pesquisa de produto criado com a Pesquisa de produto da API Vision. Há duas opções para fazer isso:

Opção 1: usar o back-end de demonstração que foi implantado para você

Para continuar com este codelab, use o back-end da Pesquisa de produtos que o Google já implantou para você. O back-end de demonstração pode ser replicado seguindo o guia de início rápido da Pesquisa de produtos da API Vision.

Opção 2: crie seu próprio back-end seguindo o guia de início rápido da Pesquisa de produtos da API Vision

Essa opção é recomendada para quem quer aprender em detalhes sobre como criar um back-end de pesquisa de produtos, para que você possa criar um para seu próprio catálogo de produtos mais tarde. Você precisa ter o seguinte:

  • Uma conta do Google Cloud com o faturamento ativado. (pode ser uma conta de teste gratuita);
  • Algum conhecimento sobre os conceitos do Google Cloud, incluindo projetos, contas de serviço etc.

Saiba como fazer isso no programa de aprendizado.

Conheça os conceitos importantes

Você encontrará estes conceitos ao interagir com o back-end de pesquisa de produto:

  • Conjunto de produtos: um conjunto de produtos é um contêiner simples de um grupo de produtos. Um catálogo de produtos pode ser representado como um conjunto de produtos e os respectivos produtos.
  • Produto: depois de criar um conjunto de produtos, você poderá criar itens e adicioná-los a ele.
  • Imagens de referência do produto: imagens que contêm várias visualizações dos seus produtos. As imagens de referência são usadas para pesquisar produtos visualmente semelhantes.
  • Pesquisar produtos: depois de criar o conjunto de produtos e indexá-lo, será possível consultar o conjunto usando a API Cloud Vision.

Como funciona o catálogo de produtos predefinido

O back-end de demonstração do Google Shopping usado neste codelab foi criado usando a Pesquisa de produtos da API Vision e um catálogo de produtos com cerca de cem sapatos e imagens de vestidos. Veja algumas imagens do catálogo:

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

Exemplos do catálogo de produtos predefinido

Chamar o back-end de demonstração da pesquisa de produtos

Para chamar a Pesquisa de produtos da API Vision diretamente de um app para dispositivos móveis, configure uma chave de API do Google Cloud e restrinja o acesso a ela apenas para o app.

Para simplificar este codelab, foi configurado um endpoint de proxy que permite acessar o back-end de demonstração sem se preocupar com a chave de API e a autenticação. Ele recebe a solicitação HTTP do app para dispositivos móveis, anexa a chave de API e encaminha a solicitação ao back-end da Pesquisa de produtos da API Vision. Em seguida, o proxy recebe a resposta do back-end e a retorna para o app para dispositivos móveis.

Neste codelab, você usará duas APIs da Pesquisa de produtos da API Vision:

6. Implementar o cliente da API

Entender o fluxo de trabalho de pesquisa de produtos

Siga este fluxo de trabalho para realizar uma pesquisa de produto com o back-end:

Implementar a classe de cliente da API

Agora, implemente um código para chamar o back-end da Pesquisa de produtos em uma classe dedicada chamada ProductSearchAPIClient. Parte do código boilerplate foi implementado no aplicativo inicial:

  • class ProductSearchAPIClient: essa classe está vazia agora, mas tem alguns métodos que você implementará mais tarde neste codelab.
  • fun convertBitmapToBase64(bitmap: Bitmap): converte uma instância de bitmap na representação base64 dela para enviar ao back-end de pesquisa de produtos.
  • fun annotateImage(image: Bitmap): Task<List<ProductSearchResult>>: chame a API projects.locations.images.annotation e analise a resposta.
  • fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult>: chame a API projects.locations.products.referenceImages.get e analise a resposta.
  • SearchResult.kt: esse arquivo contém várias classes de dados para representar os tipos retornados pelo back-end da Pesquisa de produtos da API Vision.

Especificar as configurações da API

Na classe ProductSearchAPIClient, veja algumas configurações do back-end de pesquisa de produtos já definidas:

// 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 é o endpoint da API Cloud Vision. Ao continuar com o back-end de demonstração, defina essa opção como o endpoint do proxy. No entanto, se você implantar seu próprio back-end, vai precisar alterá-lo para o endpoint da API Cloud Vision. https://vision.googleapis.com/v1.
  • VISION_API_KEY é a chave de API do projeto do Cloud. Como o proxy já processa a autenticação, você pode deixar esse campo em branco.
  • VISION_API_PROJECT_ID é o ID do projeto do Cloud. odml-codelabs é o projeto do Cloud em que o back-end de demonstração está implantado.
  • VISION_API_LOCATION_ID é o local do Cloud em que o back-end da pesquisa de produtos está implantado. us-east1 implantamos o back-end de demonstração.
  • VISION_API_PRODUCT_SET_ID é o código do catálogo de produtos (também conhecido como "conjunto de produtos" no termo API do Vision) em que você quer pesquisar produtos visualmente semelhantes. É possível ter vários catálogos em um projeto do Cloud. product_set0 é o catálogo de produtos predefinido do back-end de demonstração.

7. Chamar a API Product Search

Explorar o formato da resposta e da solicitação da API

É possível encontrar produtos semelhantes para uma determinada imagem ao transmitir o URI, o URL da Web ou a string codificada em Base64 da imagem para a Pesquisa de produtos da API Vision. Neste codelab, você usará a opção de string codificada em base64, já que nossa imagem de consulta existe apenas no dispositivo do usuário.

Você precisa enviar uma solicitação POST para o endpoint projects.locations.images.annotation com este corpo JSON da solicitação:

{
  "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"
          ],
        }
      }
    }
  ]
}

Há alguns parâmetros que precisam ser especificados:

  • base64-encoded-image: a representação em Base64 (string ASCII) dos dados binários da imagem de consulta.
  • project-id: o ID do projeto do GCP.
  • location-id: um identificador de local válido.
  • product-set-id: o ID do conjunto de produtos no qual você quer executar a operação.

Como seu catálogo de produtos contém apenas sapatos e imagens para vestidos, especifique as productCategories como apparel-v2. v2 significa que usamos a versão 2 do modelo de machine learning de pesquisa de produtos de vestuário.

Se a solicitação for bem-sucedida, o servidor retornará um código de status HTTP 200 OK e a resposta no formato JSON. A resposta JSON inclui os dois tipos de resultados a seguir:

  • productSearchResults: contém uma lista de produtos correspondentes para a imagem inteira.
  • productGroupedResults: contém coordenadas da caixa delimitadora e itens correspondentes para cada produto identificado na imagem.

Como o produto já foi cortado da imagem original, os resultados serão analisados na lista productSearchResults.

Veja alguns campos importantes no objeto do resultado da pesquisa do produto:

  • product.name: o identificador exclusivo de um produto no formato projects/{project-id}/locations/{location-id}/products/{product_id}
  • product.score: um valor que indica como o resultado da pesquisa é semelhante à imagem da consulta. Valores mais altos significam mais semelhança.
  • product.image: o identificador exclusivo da imagem de referência de um produto no formato projects/{project-id}/locations/{location-id}/products/{product_id}/referenceImages/{image_id}. Será necessário enviar outra solicitação de API a projects.locations.products.referenceImages.get para conseguir o URL dessa imagem de referência e exibi-la na tela.
  • product.labels: uma lista de tags predefinidas do produto. Isso é útil se você quer filtrar os resultados da pesquisa para mostrar apenas uma categoria de roupas, como vestidos.

Converter a imagem da consulta em base64

Você precisa converter a imagem da consulta na representação de string base64 dela e anexar a string ao objeto JSON no corpo da solicitação.

Acesse a classe ProductSearchAPIClient, encontre o método vazio convertBitmapToBase64 e substitua-o por esta implementação:

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)
}

Implementar a chamada de API

Em seguida, crie uma solicitação de API de pesquisa de produtos e envie-a ao back-end. Use o Volley para fazer a solicitação da API e retorne o resultado usando a API Task.

Volte para a classe ProductSearchAPIClient, encontre o método vazio annotateImage e substitua-o por esta implementação:

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
}

Mostrar o resultado da pesquisa na IU

Agora, o código da API em ProductSearchAPIClient está pronto. Volte à atividade ProductSearchActivity para implementar o código da IU.

A atividade já tem um código boilerplate que aciona o método searchByImage(queryImage: Bitmap). Adicione o código para chamar o back-end e mostrar os resultados na IU nesse método atualmente vazio.

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

O método showSearchResult contém um código boilerplate que analisa a resposta da API e mostra as resultados na tela.

Executar

Agora, clique em Run ( execute.png) na barra de ferramentas do Android Studio. Quando o app for carregado, toque em qualquer imagem predefinida, selecione um objeto detectado, toque no botão Pesquisar e veja os resultados da pesquisa retornados do back-end. Você verá algo como:

bb5e7c27c283a2fe.png

Captura de tela da página de resultados da pesquisa do produto

O back-end já retorna uma lista de produtos visualmente semelhantes do catálogo de produtos predefinido. No entanto, a imagem do produto ainda está vazia. O endpoint projects.locations.images.annotation só retorna IDs de imagem do produto, como projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77. Você precisará fazer outra chamada de API para o endpoint projects.locations.products.referenceImages.get e acessar o URL dessa imagem de referência para exibi-la na tela.

8. Obter as imagens de referência do produto

Explorar o formato da resposta e da solicitação da API

Você enviará uma solicitação HTTP HTTP com um corpo de solicitação vazio para o endpoint projects.locations.products.referenceImages.get e receba os URIs das imagens do produto retornadas pelo endpoint de pesquisa de produtos.

A solicitação HTTP tem esta aparência:

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

Quando a solicitação é bem-sucedida, o servidor retorna um código de status HTTP "200 OK" e a resposta no formato JSON abaixo:

{
  "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: o identificador da imagem de referência
  • uri: o URI da imagem no Google Cloud Storage (GCS).

As imagens de referência do back-end da Pesquisa de produtos de demonstração foram configuradas para ter permissão de leitura pública. Portanto, é fácil converter o URI do GCS em um URL HTTP e exibi-lo na IU do app. Só é necessário substituir o prefixo gs:// por https://storage.googleapis.com/.

Implementar a chamada de API

Em seguida, crie uma solicitação de API de pesquisa de produtos e envie-a ao back-end. Você usará o Volley e a API Task de forma semelhante à chamada de API do Product Search.

Volte para a classe ProductSearchAPIClient, encontre o método vazio fetchReferenceImage e substitua-o por esta implementação:

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
}

Esse método usa um objeto searchResult: ProductSearchResult que foi retornado pelo endpoint da pesquisa de produtos e, em seguida, segue estas etapas:

  1. Chama o endpoint da imagem de referência para conseguir o URI do GCS da imagem de referência.
  2. Converte o URI do GCS em um URL HTTP.
  3. Atualiza a propriedade httpUri do objeto searchResult com esse URL HTTP.

Conecte as duas solicitações de API

Volte para annotateImage e modifique-o para receber todos os URLs HTTP das imagens de referência antes de retornar a lista ProductSearchResult ao autor da chamada.

Encontre esta linha:

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

Em seguida, substitua-o por esta implementação:

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

O código boilerplate para exibir as imagens de referência na tela já foi implementado na classe ProductSearchAdapter para que você possa executar o app novamente.

Executar

Agora, clique em Run ( execute.png) na barra de ferramentas do Android Studio. Depois que o app for carregado, toque em qualquer imagem predefinida, selecione um objeto detectado e toque no botão Pesquisar para ver os resultados da pesquisa, desta vez com as imagens do produto.

Os resultados da pesquisa do produto fazem sentido para você?

25939f5a13eeb3c3.png

9. Parabéns!

Você aprendeu a chamar um back-end da Pesquisa de produtos da API Vision para adicionar o recurso de pesquisa de imagens de produtos ao app Android. Isso é tudo o que você precisa para começar a usar.

Ao continuar, você poderá criar seu próprio back-end usando seu catálogo de produtos. Confira o próximo codelab no programa de aprendizado da Pesquisa de imagens do produto para saber como criar seu próprio back-end e configurar a chave de API para chamá-lo em um app para dispositivos móveis.

O que vimos

  • Como chamar o back-end da Pesquisa de produtos da API Vision de um app Android

Próximas etapas

Saiba mais