Construir um QR Scanner: um tutorial de câmera nativa do React
Publicados: 2022-03-11Neste tutorial do React Native Camera, criaremos um aplicativo de leitura de código QR. Ele poderá ler códigos QR em tempo real e renderizar seu conteúdo na tela no momento da detecção. Estaremos usando o CLI Quickstart do React Native.
(Nota: Se você precisar de ajuda para configurar isso, você sempre pode consultar a página React Native Getting Started—não se esqueça de clicar no botão “React Native CLI Quickstart”, pois “Expo CLI Quickstart” vem pré-selecionado no momento de escrever este artigo.)
Por que Reagir Nativo?
O React Native é uma estrutura valiosa que empresta o paradigma e os princípios de design do React para permitir o desenvolvimento rápido e multiplataforma de interfaces de usuário rápidas. Facebook, Airbnb, Uber e muitos outros já têm seus aplicativos mais recentes criados com React Native.
O que é React Native Camera?
React Native Camera (RNCamera) é o componente principal quando se trata de implementar a funcionalidade da câmera em um aplicativo React Native. Este componente ajuda você a se comunicar com o sistema operacional nativo por meio de algumas funções simples para que você possa usar o hardware do dispositivo. Você pode criar seus aplicativos em torno dessas funções sem se preocupar com o código nativo. RNCamera já suporta:
- Fotografias
- Vídeos
- Detecção de rosto
- Leitura de código de barras
- Reconhecimento de texto (somente Android)
Observe que o RNCamera costumava vir em dois sabores:
- RNCamera
- RCTCamera (obsoleto)
…então certifique-se de usar RNCamera para que você possa continuar recebendo as atualizações mais recentes.
Nota: O React Native Camera é fortemente baseado no módulo de câmera Expo e alternar entre os dois é muito fácil.
Criando seu primeiro aplicativo usando RNCamera
Antes de começarmos nosso scanner QR React Native, há algumas dependências que precisaremos instalar.
Instalando as dependências do RNCamera
Nossa configuração precisa de um mínimo de JDK versão 1.7 (que você provavelmente tem) e se você estiver no Android, precisará de buildToolsVersion
mais recente que 25.0.2. (Para ter certeza, há uma lista mais detalhada e atualizada nos documentos.)
Primeiro vamos começar criando um novo projeto React Native:
react-native init CameraExample
Agora vamos implantar a primeira versão do nosso exemplo React Native Camera em nosso telefone.
cd CameraExample react-native run-android
Ele deve se parecer com a captura de tela abaixo:
Agora é hora de instalar o pacote react-native-camera
em nosso projeto. Usaremos a opção “Principalmente instalação automática com react-native”. (Existem outras como instalação automática com CocoaPods e instalação manual, mas vamos nos ater à primeira opção, pois é a mais eficiente.) Basta executar:
npm install react-native-camera --save react-native link react-native-camera
Você também deve adicionar as seguintes permissões a android/app/src/main/AndroidManifest.xml
:
package="com.cameraexample"> <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.CAMERA" /> + <uses-permission android:name="android.permission.RECORD_AUDIO"/> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:name=".MainApplication"
Você também precisará definir a estratégia de dimensão em android/app/build.gradle
— ela não tem padrão e você receberá um erro se não a definir:
defaultConfig { applicationId "com.cameraexample" minSdkVersion rootProject.ext.minSdkVersion + missingDimensionStrategy 'react-native-camera', 'general' targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0"
Observação: a estratégia de dimensão normalmente deve ser definida como general
, conforme descrito acima. No entanto, você pode configurá-lo para mlkit
, se quiser usar o MLKit para reconhecimento de texto/face/código de barras.
Após a instalação, você precisará usar run-android
para instalar as novas dependências:
react-native run-android
Se tudo correu bem, você deverá ver a mesma tela de boas-vindas do React Native no seu dispositivo ou simulador novamente.
Configurando a Câmera
Primeiro, vamos começar modificando App.js
e importando RNCamera
lá:
import { RNCamera } from 'react-native-camera';
Em seguida, modificaremos a função de render
para incluir nosso RNCamera
recém-importado. Observe o atributo de style
adicionado à câmera para que ela ocupe a tela inteira. Sem esses estilos, talvez você não consiga ver a renderização da câmera na tela, pois ela não ocupará nenhum espaço:
render() { return ( <View style={styles.container}> - <Text style={styles.welcome}>Welcome to React Native!</Text> - <Text style={styles.instructions}>To get started, edit App.js</Text> - <Text style={styles.instructions}>{instructions}</Text> + <RNCamera + ref={ref => { + this.camera = ref; + }} + style={{ + flex: 1, + width: '100%', + }} + > + </RNCamera> </View> ); }
Após adicionar este código, sua interface deverá estar com a câmera ligada, em tela cheia, assim como na captura de tela abaixo:
Agora podemos ver códigos de barras (como podemos ver nossos códigos QR de teste exibidos no monitor acima), mas ainda não podemos lê-los. Vamos usar o algoritmo do RNCamera para reconhecer o que está escrito dentro de cada um deles.

Lendo informações de código de barras
Para ler as informações do código de barras, usaremos a prop onGoogleVisionBarcodesDetected
para que possamos chamar uma função e extrair as informações. Vamos adicionar isso no componente <RNCamera>
e vinculá-lo a uma função barcodeRecognized
para cuidar disso. Observe que onGoogleVisionBarcodesDetected
retorna um objeto contendo a propriedade barcodes
, que contém uma matriz de todos os códigos de barras reconhecidos na câmera.
Observação: a tecnologia de código QR onGoogleVisionBarcodesDetected
só está disponível no Android, mas se você quiser uma abordagem multiplataforma, é melhor usar onBarCodeRead
. Ele suporta apenas um único código de barras por vez - usá-lo como substituto é deixado como exercício para o leitor.
Veja como nossa <RNCamera>
deve ficar depois de adicionar onGoogleVisionBarcodesDetected
:
<RNCamera ref={ref => { this.camera = ref; }} style={{ flex: 1, width: '100%', }} onGoogleVisionBarcodesDetected={this.barcodeRecognized} > </RNCamera>
E agora podemos manipular os códigos de barras no App.js
com a função abaixo, que só nos avisará quando um código de barras for detectado e deverá exibir seu conteúdo na tela:
barcodeRecognized = ({ barcodes }) => { barcodes.forEach(barcode => console.warn(barcode.data)) };
Veja como fica em ação:
Renderizando sobreposições de código de barras
A captura de tela anterior agora mostra as informações contidas no código de barras, mas não nos permite saber qual mensagem pertence a qual código de barras. Para isso, aprofundaremos os códigos de barcodes
retornados de onGoogleVisionBarcodesDetected
e tentaremos identificar cada um dos códigos de barras em nossa tela.
Mas primeiro, precisaremos salvar os códigos de barras reconhecidos no estado para que possamos acessá-los e renderizar uma sobreposição com base nos dados contidos. Agora vamos modificar nossa função definida anteriormente para ficar assim:
barcodeRecognized = ({ barcodes }) => this.setState({ barcodes });
Agora precisaremos adicionar um objeto de state
inicializado em uma matriz vazia de códigos de barras para que não crie erros em nossas funções de render
:
export default class App extends Component<Props> { state = { barcodes: [], } // ...
Vamos agora criar a função renderBarCodes
que deve ser adicionada dentro do componente <RNCamera>
:
<RNCamera ref={ref => { this.camera = ref; }} style={{ flex: 1, width: '100%', }} onGoogleVisionBarcodesDetected={this.barcodeRecognized} > {this.renderBarcodes()} </RNCamera>
Esta função agora deve pegar os códigos de barras reconhecidos do estado e mostrá-los na tela:
renderBarcodes = () => ( <View> {this.state.barcodes.map(this.renderBarcode)} </View> );
Observe que o mapeamento é apontado para renderBarcode
que deve renderizar cada código de barras na tela. Adicionei alguns estilos menores para que possamos reconhecê-los facilmente:
renderBarcode = ({ bounds, data }) => ( <React.Fragment key={data + bounds.origin.x}> <View style={{ borderWidth: 2, borderRadius: 10, position: 'absolute', borderColor: '#F00', justifyContent: 'center', backgroundColor: 'rgba(255, 255, 255, 0.9)', padding: 10, ...bounds.size, left: bounds.origin.x, top: bounds.origin.y, }} > <Text style={{ color: '#F00', flex: 1, position: 'absolute', textAlign: 'center', backgroundColor: 'transparent', }}>{data}</Text> </View> </React.Fragment> );
Cada código de barras reconhecido possui:
- Uma propriedade de
bounds
para nos dizer onde em nossa tela o código de barras foi encontrado, que usaremos para renderizar a sobreposição para ele - Uma propriedade
data
que nos mostra o que está codificado nesse código de barras específico - Uma propriedade de
type
que nos diz que tipo de código de barras é (2D, QR, etc.)
Usando esses três parâmetros como temos na função de renderização acima dá o seguinte resultado:
Implantação multiplataforma
Conforme mencionado, o RNCamera abstrai as partes nativas do módulo da câmera em uma linguagem universal de plataforma cruzada. É importante observar que alguns dos recursos estariam disponíveis apenas em uma plataforma ou podem ter uma maneira diferente de serem escritos em outra. Para garantir que o que você pretende construir seja compatível com todas as plataformas necessárias, leia sempre a documentação como primeiro passo. Além disso, é sempre melhor testar os casos extremos em dispositivos diferentes depois de concluir a implementação, para ter certeza da robustez do seu produto.
Vá em frente e decodifique
Espero que este pequeno gostinho do desenvolvimento de realidade aumentada tenha sido útil e que agora você tenha o aplicativo React Native Camera básico em execução no seu telefone ou simulador. Sinta-se à vontade para deixar um comentário se tiver alguma dúvida ou solicitação!