Manipulando a câmera no React Native com o react-native-camera

Hoje em dia muitas aplicações necessitam capturar imagens de alguma maneira para que possam implementar funcionalidades como leitura de código de barras, cadastro de produtos em uma loja virtual e até mesmo para realizar a vistoria cautelar em veículos.

No post de hoje veremos como criar um aplicativo que faça uso da Câmerado dispositivo com o React Native e usando o pacote react-native-camera, veja abaixo o resultado final:

Iniciando o projeto

Para iniciar o projeto vamos utilizar o React Native CLI, com ele instalado basta executar o comando:

react-native init ReactNativeCamera

Com o projeto criado vamos instalar o react-native-camera:

yarn add react-native-camera
// npm install react-native-camera

E como se trata de um recurso nativo do dispositivo temos que criar o linkentre o Javascript e o Código Nativo, e para isso basta executar:

react-native link react-native-camera

Configurando o react-native-camera

IOS

Nesse ponto, sua aplicação já deve estar funcionando no simulador do IOS, para testar basta no terminal/prompt executar:

react-native run-ios

Porém se você for rodar a aplicação no seu dispositivo físico IOS será necessário um pequeno ajuste, temos que adicionar 2 permissões no arquivo ios/ReactNativeCamera/info.plist, abaixo segue o detalhe das permissões a serem adicionadas.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	...
	<key>NSCameraUsageDescription</key>
	<string>Your message to user when the camera is accessed for the first time</string>
	<key>NSPhotoLibraryUsageDescription</key>
	<string>Your message to user when the photo library is accessed for the first time</string>
</dict>
</plist>

Android

Já se você tentar abrir o aplicativo no Android Studio, provavelmente irá acontecer o erro mostrado abaixo.

Gradle 'android' project refresh failed
    Could not find method google() for arguments [] on repository container.

E isso acontece devido a versão do Gradle instalada no projeto, por padrão o React Native CLI cria o projeto com a versão 2.2.3 instalada, e para que o react-native-camera funcione corretamente teremos que fazer a atualização para a versão 3.1.0, o processo é um pouco trabalhoso, mas não se preocupe que te mostrarei em detalhes como realizá-lo.

Primeiramente vamos modificar a URL de onde são buscadas as informações do Gradle, para isso vamos modificar o arquivo android/gradle/wrapper/gradle-wrapper.properties, ficando assim:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

Feito isso o próximo passo é atualizar o arquivo android/build.gradle, ficando assim:

buildscript {
  repositories {
    ...
    google() // Linha Adicionada
  }
  dependencies {
    // Versão modificada de 2.2.3 para 3.1.0
    classpath 'com.android.tools.build:gradle:3.1.0'
  }
}
allprojects {
  repositories {
    ...
    google() // Linha Adicionada
    maven { url "https://jitpack.io" } // Linha Adicionada
    maven {
      url "$rootDir/../node_modules/react-native/android"
    }
  }
}
// Adicionar todo o trecho abaixo
subprojects {
  project.configurations.all {
    resolutionStrategy.eachDependency { details ->
      if (details.requested.group == 'com.android.support'
          && !details.requested.name.contains('multidex') ) {
        details.useVersion "26.1.0"
      }
    }
  }
}

E por último temos que modificar a versão do SDK e do Build Tools usados para o build do aplicativo no arquivo android/app/build.gradle, no seu projeto eles devem estar com a versão 23, que vem por padrão, basta mudar ambos para a versão 26, como abaixo:

...
android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
...

Agora salve todos seus arquivos, cruze os dedos e abra o projeto novamente no Android Studio, dessa vez ele deve conseguir completar o processo com sucesso, mesmo com alguns Warnings, os quais você não precisa se preocupar.

Para testar abra o AVD do Android Studio ou outra alternativa de emulador e execute:

react-native run-android

Criando a aplicação para usar a Câmera

Antes de começarmos com o código em React Native, caso você ainda não conheça o framework, ou quer reforçar seus conhecimentos em Javascripte ES6/ES7/ ES8, dê uma olhada nos nossos mini-cursos gratuitos.

Sem mais delongas vamos para o código \o/

O código completo para consulta pode ser encontrado aqui.

O primeiro passo é adicionar a importação do componente de câmera que configuramos anteriormente, o pacote react-native-camera exporta um componente chamado RNCamera, segue abaixo como ficou a importação:

import { RNCamera } from 'react-native-camera';

Com o RNCamera devidamente importado vamos inseri-lo, abaixo segue a implementação com as props configuradas:

<RNCamera
  ref={camera => { this.camera = camera }}
  style = {styles.preview}
  type={RNCamera.Constants.Type.back}
  autoFocus={RNCamera.Constants.AutoFocus.on}
  flashMode={RNCamera.Constants.FlashMode.off}
  permissionDialogTitle={'Permission to use camera'}
  permissionDialogMessage={'We need your permission to use your camera phone'}
/>

Vamos às explicações de algumas das props:

  • type – Prop para indicar se a câmera utilizada será a frontal ou traseira.
  • autoFocus – Prop usada para a câmera utilizar ou não a função de focar automaticamente um ponto da imagem.
  • flashMode – Prop para indicar se ao capturar a imagem o Flash da câmera deve ser usado.
  • permissionDialogTitle e permissionDialogTitle – Props apenas para dispositivos com Android na versão Marshmellow ou superior, que requerem permissão para o uso de alguns recursos, e a câmera é um deles.

Para consultar todas as props disponíveis com os valores que cada uma aceita desse componente você pode entrar nesse link.

Com o componente de câmera devidamente implementado vamos criar o botão de captura, para isso vamos usar um TouchableOpacity com um Text, o código abaixo deve ser inserido após o componente RNCamera.

<View style={styles.buttonContainer}>
  <TouchableOpacity onPress={this.takePicture} style={styles.capture}>
    <Text style={styles.buttonText}> SNAP </Text>
  </TouchableOpacity>
</View>

E por último vamos criar a função chamada no botão, a takePicture, vamos criá-la dentro do componente App porém antes do método render, o código dela vai ficar assim:

takePicture = async () => {
  if (this.camera) {
    const options = { quality: 0.5, base64: true };
    const data = await this.camera.takePictureAsync(options)
    alert(data.uri);
  }
}

Logo no início da função temos uma verificação para saber se variável criada na prop ref do componente RNCamera existe, caso ela exista vamos criar um objeto options com algumas configurações que queremos na imagem, para consultar todas as options disponíveis basta acessar esse link, na próxima linha criamos uma variável data recebendo a execução da função takePictureAsync(), que é a responsável por capturar a imagem.

Concluindo

Com tudo criado você pode testar o funcionamento da câmera, mas como não criamos nenhum estilo o visual da aplicação pode não funcionar muito bem, você pode consultar o arquivo final com os estilos configurados no repositório do projeto.

E por hoje é isso galera 😀 Se gostou do post (ou não), deixe seu comentário e seu feedback.

Apenas reforçando, corre lá para dar uma olhada nos nossos mini-cursos gratuitos e se quer aprender React Native a fundo já deixei seu nome na lista de espera do GoNative.

Abraços e até a próxima \o/