Compartilhar via


Tutorial: Criar um aplicativo Web de análise de imagem com TypeScript

Neste tutorial, você aprenderá a criar e implantar localmente um aplicativo cliente React/TypeScript em um aplicativo Web estático do Azure com uma ação do GitHub. O aplicativo React permite que você analise uma imagem com a Pesquisa Visual Computacional dos Serviços Cognitivos.

Neste tutorial, você aprenderá a:

  • Criar recursos do Azure com a CLI do Azure
  • Adicionar variáveis de ambiente ao ambiente remoto
  • Usar a ação do GitHub com variáveis de ambiente
  • Exibir aplicativo Web implantado

Pré-requisitos

  • Conta de usuário do Azure com uma assinatura ativa. Crie um gratuitamente.
  • Node.js e npm – instalados em seu computador local.
  • Visual Studio Code – instalado no computador local.
  • Git – usado para enviar por push para o GitHub, o que ativa a ação do GitHub.
  • Conta do GitHub - para bifurcar e enviar por push para um repositório.
  • Use o Azure Cloud Shell usando o ambiente bash.
  • Sua conta do Azure deve ter a função Colaborador dos Serviços Cognitivos atribuída para que você concorde com os termos e condições da IA responsável e crie um recurso. Para que essa função seja atribuída à sua conta, siga as etapas descritas na documentação Atribuir funções ou entre em contato com o administrador.

O que é um aplicativo Web estático do Azure

Ao criar aplicativos Web estáticos, você tem várias opções no Azure, com base no grau de funcionalidade e controle em que está interessado. Este tutorial se concentra no serviço mais fácil, com muitas das opções feitas para você, para que você possa se concentrar no código de front-end e não no ambiente de hospedagem.

O React (create-react-app) oferece a seguinte funcionalidade:

  • Exibir uma mensagem se a chave e o ponto de extremidade do Azure para a Pesquisa Visual Computacional dos Serviços Cognitivos não forem encontrados
  • Permite analisar uma imagem com a Pesquisa Visual Computacional dos Serviços Cognitivos
    • Inserir uma URL de imagem pública ou analisar imagem de uma coleção
    • Quando a análise estiver concluída
      • Exibir imagem
      • Exibir resultados em JSON da Pesquisa Visual Computacional

Captura de tela dos resultados de exemplo da Pesquisa Visual Computacional do Serviço Cognitivo React.

Para implantar o aplicativo Web estático, use uma ação do GitHub, que começa quando ocorre um push para um branch específico:

  • Insere segredos do GitHub para chave e ponto de extremidade da Pesquisa Visual Computacional no build
  • Cria o cliente React (create-react-app)
  • Move os arquivos resultantes para o recurso de aplicativo Web estático do Azure

Criar fork do repositório de exemplo

Crie um fork do repositório em vez de apenas cloná-lo no computador local, para ter seu próprio repositório do GitHub para o qual enviar as alterações por push.

  1. Abra uma janela ou guia separada do navegador e entre no GitHub.

  2. Navegue até o repositório de exemplo do GitHub.

    https://github.com/Azure-Samples/js-e2e-client-cognitive-services
    
  3. Na seção superior direita da página, selecione Criar fork.

  4. Selecione Código e, em seguida, copie a URL do local para seu fork.

    Captura de tela do site do GitHub, selecione **Código** e copie o local do seu fork.

Criar ambiente de desenvolvimento local

  1. Em uma janela de terminal ou bash, clone o fork no computador local. Substitua YOUR-ACCOUNT-NAME pelo nome da sua conta do GitHub.

    git clone https://github.com/YOUR-ACCOUNT-NAME/js-e2e-client-cognitive-services
    
  2. Altere para o novo diretório e instale as dependências.

    cd js-e2e-client-cognitive-services && npm install
    

    A etapa de instalação instala as dependências necessárias, incluindo @azure/cognitiveservices-computervision.

Executar o exemplo local

  1. Execute o exemplo.

    npm start
    

    Captura de tela do exemplo de Pesquisa Visual Computacional do Serviço Cognitivo React para análise de imagem antes da chave e do ponto de extremidade definidos.

  2. Interrompa o aplicativo. Feche a janela do terminal ou use control+c no terminal.

Criar seu grupo de recursos

Em um shell de terminal ou do bash, insira o comando CLI do Azure para criar um grupo de recursos do Azure, com o nome rg-demo:

az group create \
    --location eastus \
    --name rg-demo \
    --subscription YOUR-SUBSCRIPTION-NAME-OR-ID

Criar um recurso da Pesquisa Visual Computacional

A criação de um grupo de recursos permite que você encontre facilmente os recursos e exclua-os quando terminar. Esse tipo de recurso requer que você concorde com o contrato de Uso Responsável. Use a seguinte lista para saber como você pode criar rapidamente o recurso correto:

Criar seu primeiro recurso de Pesquisa Visual Computacional

Se esse for seu primeiro serviço de IA, você precisará criar o serviço por meio do portal e concordar com o contrato de Uso Responsável, como parte da criação do recurso. Se esse não for seu primeiro recurso que exige o contrato de Uso Responsável, você poderá criar o recurso com a CLI do Azure, encontrado na próxima seção.

Use a tabela a seguir para ajudar a criar o recurso dentro do portal do Azure.

Configuração Valor
Grupo de recursos rg-demo
Nome demo-ComputerVision
Sku S1
Location eastus

Criar um recurso de Pesquisa Visual Computacional adicional

Execute o seguinte comando para criar um recurso da Pesquisa Visual Computacional:

az cognitiveservices account create \
    --name demo-ComputerVision \
    --resource-group rg-demo \
    --kind ComputerVision \
    --sku S1 \
    --location eastus \
    --yes

Obter chaves e ponto de extremidade de recurso da Pesquisa Visual Computacional

  1. Nos resultados, localize e copie o properties.endpoint. Você precisará disso mais tarde.

    ...
    "properties":{
        ...
        "endpoint": "https://eastus.api.cognitive.microsoft.com/",
        ...
    }
    ...
    
  2. Execute o comando a seguir para obter as chaves.

    az cognitiveservices account keys list \
    --name demo-ComputerVision \
    --resource-group rg-demo
    
  3. Copie uma das chaves, você precisará dela mais tarde.

    {
      "key1": "8eb7f878bdce4e96b26c89b2b8d05319",
      "key2": "c2067cea18254bdda71c8ba6428c1e1a"
    }
    

Adicionar variáveis de ambiente ao seu ambiente local

Para usar o recurso, o código local precisa ter a chave e o ponto de extremidade disponíveis. Essa base de código as armazena em variáveis de ambiente:

  • REACT_APP_AZURE_COMPUTER_VISION_KEY
  • REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT
  1. Execute o comando a seguir para adicionar essas variáveis ao seu ambiente.

    export REACT_APP_AZURE_COMPUTER_VISION_KEY="REPLACE-WITH-YOUR-KEY"
    export REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT="REPLACE-WITH-YOUR-ENDPOINT"
    

Adicionar variáveis de ambiente ao ambiente remoto

Ao usar aplicativos Web estáticos do Azure, as variáveis de ambiente, como segredos, precisam ser passadas da ação do GitHub para o aplicativo Web estático. A ação do GitHub cria o aplicativo, incluindo a chave e o ponto de extremidade da Pesquisa Visual Computacional passados dos segredos do GitHub para esse repositório e, em seguida, envia por push o código com as variáveis de ambiente para o aplicativo Web estático.

  1. Em um navegador da Web, no repositório do GitHub, selecione Configurações, Segredos e Novo segredo de repositório.

    Captura de tela do repositório GitHub, criando um novo segredo do repositório.

  2. Insira o mesmo nome e valor para o ponto de extremidade usado na seção anterior. Em seguida, crie outro segredo com o mesmo nome e valor para a chave, conforme usado na seção anterior.

    Captura de tela de inserir o mesmo nome e valor para o ponto de extremidade. Em seguida, crie outro segredo com o mesmo nome e valor para a chave.

Execute o aplicativo de reação local com o recurso ComputerVision

  1. Inicie o aplicativo novamente, na linha de comando:

    npm start
    

    Captura de tela do exemplo de Pesquisa Visual Computacional do Serviço Cognitivo React pronto para URL ou pressione Enter.

  2. Deixe o campo de texto vazio para selecionar uma imagem do catálogo padrão e selecione o botão Analisar.

    Captura de tela dos resultados de exemplo da Pesquisa Visual Computacional do Serviço Cognitivo React.

    A imagem é selecionada aleatoriamente em um catálogo de imagens definido em ./src/DefaultImages.js.

  3. Continue para selecionar o botão Analisar para ver as outras imagens e os resultados.

Enviar o branch local para o GitHub

No terminal do Visual Studio Code, envie por push o branch local main para o repositório remoto.

git push origin main

Não é preciso fazer commit de alterações porque nenhuma alteração foi executada ainda.

Criar um recurso de aplicativo Web estático

  1. Clique no ícone Azure, clique com o botão direito do mouse no serviço Aplicativos Web Estáticos, depois clique em Criar Aplicativo Web Estático (Avançado).

    Captura de tela com a extensão do Visual Studio.

  2. Caso uma janela pop-up pergunte se você deseja continuar no branch main, clique em Continuar.

  3. Insira as informações a seguir nos campos subsequentes, apresentados um de cada vez.

    Nome do campo value
    Selecione um grupo de recursos para novos recursos. Selecione o grupo de recursos criado para o recurso ComputerVision: demo-ComputerVision.
    Insira o nome do novo aplicativo Web estático. Demo-ComputerVisionAnalyzer
    Selecionar uma opção de preço Selecione a opção gratuito.
    Selecione o local do código do aplicativo. Escolha a mesma localização selecionada durante a criação do grupo de recursos: eastus.
    Escolha a predefinição de build para configurar a estrutura de projeto padrão. React
    Selecione a localização do código do aplicativo. /
    Insira a localização do código do Azure Functions. Use o valor padrão.
    Insira o caminho da saída do build em relação ao local do seu aplicativo. build

Atualizar a ação do GitHub com variáveis de ambiente secretas

A chave e o ponto de extremidade da Pesquisa Visual Computacional estão na coleção de segredos do repositório, mas ainda não estão na ação do GitHub. Esta etapa adiciona a chave e o ponto de extremidade à ação.

  1. Puxe as alterações feitas na criação do recurso do Azure para obter o arquivo de ação do GitHub.

    git pull origin main
    
  2. No editor do Visual Studio Code, edite o arquivo de ação do GitHub encontrado em ./.github/workflows/ para adicionar os segredos.

    name: Azure Static Web Apps CI/CD
    
    on:
      push:
        branches:
          - from-local
      pull_request:
        types: [opened, synchronize, reopened, closed]
        branches:
          - from-local
    
    jobs:
      build_and_deploy_job:
        if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
        runs-on: ubuntu-latest
        name: Build and Deploy Job
        steps:
          - uses: actions/checkout@v2
            with:
              submodules: true
          - name: Build And Deploy
            id: builddeploy
            uses: Azure/static-web-apps-deploy@v0.0.1-preview
            with:
              azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_RANDOM_NAME_HERE }}
              repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
              action: "upload"
              ###### Repository/Build Configurations - These values can be configured to match you app requirements. ######
              # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
              app_location: "/" # App source code path
              api_location: "api" # Api source code path - optional
              output_location: "build" # Built app content directory - optional
              ###### End of Repository/Build Configurations ######
            env:
              REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT: ${{secrets.REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT}}
              REACT_APP_AZURE_COMPUTER_VISION_KEY:  ${{secrets.REACT_APP_AZURE_COMPUTER_VISION_KEY}}
    
      close_pull_request_job:
        if: github.event_name == 'pull_request' && github.event.action == 'closed'
        runs-on: ubuntu-latest
        name: Close Pull Request Job
        steps:
          - name: Close Pull Request
            id: closepullrequest
            uses: Azure/static-web-apps-deploy@v0.0.1-preview
            with:
              azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_RANDOM_NAME_HERE }}
              action: "close"
    
  3. Adicione e confirme a alteração no branch main local.

    git add . && git commit -m "add secrets to action"
    
  4. Envie por push a alteração para o repositório remoto, iniciando uma nova ação build-and-deploy para o aplicativo Web estático do Azure.

    git push origin main
    

Exibir o processo de build da ação do GitHub

  1. Em um navegador da Web, abra o repositório do GitHub deste tutorial e selecione Ações.

  2. Selecione o primeiro build da lista e, em seguida, selecione Trabalho de Compilar e Implantar no menu do lado esquerdo para ver o processo de build. Aguarde até que Compilar e Implantar seja concluído com êxito.

    Captura de tela da ação do GitHub ao criar o aplicativo.

Exibir site estático remoto do Azure no navegador

  1. No Visual Studio Code, selecione o ícone Azure no menu da extrema direita, selecione seu aplicativo Web estático, clique com o botão direito do mouse em Procurar site e, em seguida, selecione Abrir para exibir o site estático público.

Captura de tela do navegador da web: Selecione 'Procurar site' e, em seguida, selecione 'Abrir' para visualizar o site estático público.

Você também pode encontrar a URL para o site nos seguintes locais:

  • no portal do Azure para o recurso, na página Visão geral.
  • na saída do build-and-deploy da ação do GitHub tem a URL do site no final do script

Código: Adicionar Pesquisa Visual Computacional ao aplicativo React local

Use npm para adicionar a Pesquisa Visual Computacional ao arquivo package.json.

npm install @azure/cognitiveservices-computervision 

Código: Adicionar código de Pesquisa Visual Computacional como módulo separado

O código da Pesquisa Visual Computacional está contido em um arquivo separado chamado ./src/azure-cognitiveservices-computervision.js. A função principal do módulo é realçada.

// ./src/azure-cognitiveservices-computervision.js

// Azure SDK client libraries
import { ComputerVisionClient } from '@azure/cognitiveservices-computervision';
import { ApiKeyCredentials } from '@azure/ms-rest-js';

// List of sample images to use in demo
import RandomImageUrl from './DefaultImages';

// Authentication requirements
const key = process.env.REACT_APP_AZURE_COMPUTER_VISION_KEY;
const endpoint = process.env.REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT;

console.log(`key = ${key}`)
console.log(`endpoint = ${endpoint}`)

// Cognitive service features
const visualFeatures = [
    "ImageType",
    "Faces",
    "Adult",
    "Categories",
    "Color",
    "Tags",
    "Description",
    "Objects",
    "Brands"
];

export const isConfigured = () => {
    const result = (key && endpoint && (key.length > 0) && (endpoint.length > 0)) ? true : false;
    console.log(`key = ${key}`)
    console.log(`endpoint = ${endpoint}`)
    console.log(`ComputerVision isConfigured = ${result}`)
    return result;
}

// Computer Vision detected Printed Text
const includesText = async (tags) => {
    return tags.filter((el) => {
        return el.name.toLowerCase() === "text";
    });
}
// Computer Vision detected Handwriting
const includesHandwriting = async (tags) => {
    return tags.filter((el) => {
        return el.name.toLowerCase() === "handwriting";
    });
}
// Wait for text detection to succeed
const wait = (timeout) => {
    return new Promise(resolve => {
        setTimeout(resolve, timeout);
    });
}

// Analyze Image from URL
export const computerVision = async (url) => {

    // authenticate to Azure service
    const computerVisionClient = new ComputerVisionClient(
        new ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': key } }), endpoint);

    // get image URL - entered in form or random from Default Images
    const urlToAnalyze = url || RandomImageUrl();
    
    // analyze image
    const analysis = await computerVisionClient.analyzeImage(urlToAnalyze, { visualFeatures });

    // text detected - what does it say and where is it
    if (includesText(analysis.tags) || includesHandwriting(analysis.tags)) {
        analysis.text = await readTextFromURL(computerVisionClient, urlToAnalyze);
    }

    // all information about image
    return { "URL": urlToAnalyze, ...analysis};
}
// analyze text in image
const readTextFromURL = async (client, url) => {
    
    let result = await client.read(url);
    let operationID = result.operationLocation.split('/').slice(-1)[0];

    // Wait for read recognition to complete
    // result.status is initially undefined, since it's the result of read
    const start = Date.now();
    console.log(`${start} -${result?.status} `);
    
    while (result.status !== "succeeded") {
        await wait(500);
        console.log(`${Date.now() - start} -${result?.status} `);
        result = await client.getReadResult(operationID);
    }
    
    // Return the first page of result. 
    // Replace[0] with the desired page if this is a multi-page file such as .pdf or.tiff.
    return result.analyzeResult; 
}

Código: Adicionar catálogo de imagens como módulo separado

O aplicativo selecionará uma imagem aleatória de um catálogo se o usuário não inserir uma URL de imagem. A função de seleção aleatória está realçada

// ./src/DefaultImages.js

const describeURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/celebrities.jpg';
const categoryURLImage = 'https://moderatorsampleimages.blob.core.windows.net/samples/sample16.png';
const tagsURL = 'https://moderatorsampleimages.blob.core.windows.net/samples/sample16.png';
const objectURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-node-sdk-samples/master/Data/image.jpg';
const brandURLImage = 'https://docs.microsoft.com/en-us/azure/cognitive-services/computer-vision/images/red-shirt-logo.jpg';
const facesImageURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/faces.jpg';
const printedTextSampleURL = 'https://moderatorsampleimages.blob.core.windows.net/samples/sample2.jpg';
const multiLingualTextURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/MultiLingual.png';
const adultURLImage = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/celebrities.jpg';
const colorURLImage = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/celebrities.jpg';
// don't use with picture analysis
// eslint-disable-next-line
const mixedMultiPagePDFURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/MultiPageHandwrittenForm.pdf';
const domainURLImage = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/landmark.jpg';
const typeURLImage = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-python-sdk-samples/master/samples/vision/images/make_things_happen.jpg';

const DefaultImages = [
    describeURL,
    categoryURLImage,
    tagsURL,
    objectURL,
    brandURLImage,
    facesImageURL,
    adultURLImage,
    colorURLImage,
    domainURLImage,
    typeURLImage,
    printedTextSampleURL,
    multiLingualTextURL,
    //mixedMultiPagePDFURL
];

const RandomImageUrl = () => {
    return DefaultImages[Math.floor(Math.random() * Math.floor(DefaultImages.length))];
}

export default RandomImageUrl;

Código: Adicionar módulo de Pesquisa Visual Computacional personalizado ao aplicativo React

Adicione métodos ao React app.js. A análise de imagem e a exibição de resultados estão realçadas.

// ./src/App.js

import React, { useState } from 'react';
import './App.css';
import { computerVision, isConfigured as ComputerVisionIsConfigured } from './azure-cognitiveservices-computervision';

function App() {

  const [fileSelected, setFileSelected] = useState(null);
  const [analysis, setAnalysis] = useState(null);
  const [processing, setProcessing] = useState(false);
  
  const handleChange = (e) => {
    setFileSelected(e.target.value)
  }
  const onFileUrlEntered = (e) => {

    // hold UI
    setProcessing(true);
    setAnalysis(null);

    computerVision(fileSelected || null).then((item) => {
      // reset state/form
      setAnalysis(item);
      setFileSelected("");
      setProcessing(false);
    });

  };

  // Display JSON data in readable format
  const PrettyPrintJson = (data) => {
    return (<div><pre>{JSON.stringify(data, null, 2)}</pre></div>);
  }

  const DisplayResults = () => {
    return (
      <div>
        <h2>Computer Vision Analysis</h2>
        <div><img src={analysis.URL} height="200" border="1" alt={(analysis.description && analysis.description.captions && analysis.description.captions[0].text ? analysis.description.captions[0].text : "can't find caption")} /></div>
        {PrettyPrintJson(analysis)}
      </div>
    )
  };
  
  const Analyze = () => {
    return (
    <div>
      <h1>Analyze image</h1>
      {!processing &&
        <div>
          <div>
            <label>URL</label>
            <input type="text" placeholder="Enter URL or leave empty for random image from collection" size="50" onChange={handleChange}></input>
          </div>
          <button onClick={onFileUrlEntered}>Analyze</button>
        </div>
      }
      {processing && <div>Processing</div>}
      <hr />
      {analysis && DisplayResults()}
      </div>
    )
  }
  
  const CantAnalyze = () => {
    return (
      <div>Key and/or endpoint not configured in ./azure-cognitiveservices-computervision.js</div>
    )
  }
  
  function Render() {
    const ready = ComputerVisionIsConfigured();
    if (ready) {
      return <Analyze />;
    }
    return <CantAnalyze />;
  }

  return (
    <div>
      {Render()}
    </div>
    
  );
}

export default App;

Limpar os recursos

Depois de concluir este tutorial, você precisa remover o grupo de recursos, que inclui o recurso Pesquisa Visual Computacional e o aplicativo Web estático, para garantir que você não seja cobrado por mais uso.

No VS Code, selecione o Azure Explorer, clique com o botão direito do mouse no grupo de recursos listado na assinatura e selecione Excluir.

Captura de tela parcial do VS Code selecionando o grupo de recursos na lista de grupos de recursos e clicando com o botão direito do mouse na opção 'Excluir'.