npm install --global expo-cli
Expo requer Nodejs para funcionar. Você pode executar a versão mais recente no site oficial aqui.
Começando
Depois de instalar o Expo e o Nodejs, você pode iniciar a inicialização de um novo projeto Expo com o comando abaixo:
expo init expo-camera-app
Como instalar os pacotes e executar o aplicativo
A Expo nos fornece um aplicativo cliente onde podemos executar e ver uma prévia do aplicativo que estamos construindo. Está disponível em ambos Loja de aplicativos e Google Play baixar.
Esta é a interface do aplicativo.
Como iniciar um projeto expo
Vá para o diretório do aplicativo e execute o aplicativo.
cd expo-camera-app
Serão feitas algumas perguntas para selecionar o modelo padrão para o aplicativo. Neste tutorial, simplesmente selecionamos uma opção em branco (TypeScript), mas, novamente, você é livre para escolher o que é certo para você.
Execute o aplicativo
Depois de inicializar o projeto, podemos executar o aplicativo com expo run
Isso abrirá uma janela em seu navegador onde você pode ver os logs. Ele também irá gerar um código QR que você pode escanear para executar o aplicativo em seu dispositivo.
O bom do expo é que você não precisa instalar e configurar os simuladores para executar o aplicativo. Ele ainda oferece a opção de executar o expo no simulador, mas você deve instalar e configurar o simulador sozinho.
De volta ao nosso aplicativo. Supondo que você tenha executado com êxito o aplicativo no dispositivo, esta será a tela padrão:
Abra o diretório do aplicativo em seu editor de código favorito. estou a usar Código VS.
o App.tsx
será parecido com isto:
import {StatusBar} from 'expo-status-bar'import React from 'react'import {StyleSheet, Text, View} from 'react-native'export default function App() { return ( <View style={styles.container}> <Text>Open up App.tsx to start working on your app!</Text> <StatusBar style="auto" /> </View> )}const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' }})
Como criar a IU
Depois de ter o projeto em execução, agora é hora de começar a criar alguma IU.
Instalar expo-camera
A próxima etapa é instalar câmera de exposição, como isso:
expo install expo-camera
Vamos criar uma interface de usuário simples que permitirá ao usuário iniciar o processo de uso da câmera.
import {StatusBar} from 'expo-status-bar'import React from 'react'import {StyleSheet, Text, View, TouchableOpacity} from 'react-native'export default function App() { return ( <View style={styles.container}> <View style={{ flex: 1, backgroundColor: '#fff', justifyContent: 'center', alignItems: 'center' }} > <TouchableOpacity style={{ width: 130, borderRadius: 4, backgroundColor: '#14274e', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', height: 40 }} > <Text style={{ color: '#fff', fontWeight: 'bold', textAlign: 'center' }} > Take picture </Text> </TouchableOpacity> </View> <StatusBar style="auto" /> </View> )}const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' }})
É uma IU simples: importamos TouchableOpacity
para o botão e faça um estilo simples. Se você está se perguntando como o estilo funciona no React Native, você pode verificar meus dois artigos aqui:
Agora temos que usar um useState
gancho para gerenciar o estado e exibir a visão da câmera quando o usuário pressiona o tire uma foto botão.
<TouchableOpacity onPress={__startCamera} style={{ width: 130, borderRadius: 4, backgroundColor: '#14274e', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', height: 40 }} > <Text style={{ color: '#fff', fontWeight: 'bold', textAlign: 'center' }} > Take picture </Text> </TouchableOpacity>
const [startCamera,setStartCamera] = React.useState(false)const __startCamera = ()=>{}
Há duas coisas importantes que devemos fazer quando o usuário pressiona o botão:
- Peça permissão para acessar a câmera. No desenvolvimento móvel, o acesso a muitas APIs nativas e recursos móveis é frequentemente restrito pelas permissões e privacidade do usuário. É apenas algo com o qual você precisa se acostumar ao desenvolver aplicativos móveis.
- Mude o estado e apresente a câmera.
Vamos importar o módulo da câmera de expo-camera
com este comando:
import {Camera} from 'expo-camera'
E adicione a visão da câmera, assim:
<Camera style={{flex: 1,width:"100%"}} ref={(r) => { camera = r }} ></Camera>
Podemos usar ref
para acessar os métodos da câmera:
let camera: Camera
Quando o take picture
botão é pressionado o __startCamera
função será chamada:
const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if(status === 'granted'){ // do something }else{ Alert.alert("Access denied") }
A função pedirá permissão primeiro. Se o usuário conceder acesso à câmera, podemos prosseguir e abrir a câmera. Caso contrário, mostramos um alerta simples.
Adicione o componente da câmera
Vamos exibir a câmera quando o usuário conceder acesso à câmera do dispositivo.
const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if (status === 'granted') { // start the camera setStartCamera(true) } else { Alert.alert('Access denied') } }
Temos que fazer algumas mudanças na IU e adicionar uma renderização condicional. Exibimos a câmera apenas quando o usuário solicita, caso contrário exibimos a tela padrão.
{startCamera ? ( <Camera style={{flex: 1,width:"100%"}} ref={(r) => { camera = r }} ></Camera> ) : ( <View style={{ flex: 1, backgroundColor: '#fff', justifyContent: 'center', alignItems: 'center' }} > <TouchableOpacity onPress={__startCamera} style={{ width: 130, borderRadius: 4, backgroundColor: '#14274e', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', height: 40 }} > <Text style={{ color: '#fff', fontWeight: 'bold', textAlign: 'center' }} > Take picture </Text> </TouchableOpacity> </View> )}
Legal, agora precisamos adicionar um botão para que possamos tirar a foto real.
Adicione o botão de captura
Este é um simples View
dentro da visão da câmera que tem uma posição absoluta. Por isso, certificamo-nos de que está sempre na parte superior da câmera.
<View style={{ position: 'absolute', bottom: 0, flexDirection: 'row', flex: 1, width: '100%', padding: 20, justifyContent: 'space-between' }} > <View style={{ alignSelf: 'center', flex: 1, alignItems: 'center' }} > <TouchableOpacity onPress={__takePicture} style={{ width: 70, height: 70, bottom: 0, borderRadius: 50, backgroundColor: '#fff' }} /> </View> </View>
Como tirar uma foto
O aplicativo deve tirar uma foto quando o botão de captura é pressionado. Essa função será semelhante a esta:
const __takePicture = async () => { if (!camera) return const photo = await camera.takePictureAsync() }
Primeiro, verificamos se temos acesso ao Camera
componente usando ref
:
if (!camera) return // if the camera is undefined or null, we stop the function execution
Então tiramos a foto chamando o takePictureAsync
método. Ele retorna uma promessa e um objeto que contém os detalhes da imagem. O resultado será assim:
Object { "height": 4224, "uri": "file:///var/mobile/Containers/Data/Application/E6740A15-93AF-4120-BF11-6E8B74AFBF93/Library/Caches/ExponentExperienceData/%2540anonymous%252Fcamera-app-ee0fa3c8-1bb1-4d62-9863-33bf26341c55/Camera/19F0C5DD-7CA6-4043-8D89-AF65A1055C7E.jpg", "width": 1952,}
Estamos interessados apenas no URL da imagem uri
. Depois de tirar uma foto, temos que mostrar a visualização da foto e ocultar a visão da câmera. Para fazer isso, usaremos dois ganchos para alterar o estado:
const [previewVisible, setPreviewVisible] = useState(false) const [capturedImage, setCapturedImage] = useState<any>(null)
const __takePicture = async () => { if (!camera) return const photo = await camera.takePictureAsync() console.log(photo) setPreviewVisible(true) setCapturedImage(photo) }
-
setPreviewVisible
para mostrar a prévia setCapturedImage(photo)
para armazenar o resultado do objeto
Em seguida, exibimos a visualização assim:
{previewVisible && capturedImage ? ( <CameraPreview photo={capturedImage} /> ) : ( <Camera style={{flex: 1}} ref={(r) => { camera = r }} > <View style={{ flex: 1, width: '100%', backgroundColor: 'transparent', flexDirection: 'row' }} > <View style={{ position: 'absolute', bottom: 0, flexDirection: 'row', flex: 1, width: '100%', padding: 20, justifyContent: 'space-between' }} > <View style={{ alignSelf: 'center', flex: 1, alignItems: 'center' }} > <TouchableOpacity onPress={__takePicture} style={{ width: 70, height: 70, bottom: 0, borderRadius: 50, backgroundColor: '#fff' }} /> </View> </View> </View> </Camera> )}
o CameraPreview
componente tem a seguinte aparência:
const CameraPreview = ({photo}: any) => { console.log('sdsfds', photo) return ( <View style={{ backgroundColor: 'transparent', flex: 1, width: '100%', height: '100%' }} > <ImageBackground source={{uri: photo && photo.uri}} style={{ flex: 1 }} /> </View> )}
E o resultado é o seguinte:
Como tirar uma foto novamente
Podemos adicionar alguns botões à visualização que permitirão ao usuário realizar mais ações. Por exemplo, eles podem tirar a foto novamente ou salvá-la.
Adicione o savePhoto
e retakePicture
adereços para o CameraPreview
componente como este:
<CameraPreview photo={capturedImage} savePhoto={__savePhoto} retakePicture={__retakePicture} />
Quando o Re-take
for pressionado, teremos que ocultar a visualização, remover a imagem atual e mostrar a câmera novamente. Faça isso com o seguinte código:
const __retakePicture = () => { setCapturedImage(null) setPreviewVisible(false) __startCamera() }
Como adicionar outras opções – câmera traseira, flash e mais
Expo-camra oferece muitas opções para personalizar a câmera, como FlashMode, definir o tipo de câmera (frente / trás), zoom e assim por diante.
Como adicionar FlashMode
Vamos adicionar uma opção para que o usuário possa ligar e desligar FlashMode:
Simplesmente criamos um pequeno botão para desligar / ligar o flash, como este:
<TouchableOpacity onPress={__handleFlashMode} style={{ position: 'absolute', left: '5%', top: '10%', backgroundColor: flashMode === 'off' ? '#000' : '#fff', borderRadius: '50%', height: 25, width: 25 }} > <Text style={{ fontSize: 20 }} > ⚡️ </Text> </TouchableOpacity>
E apenas mudamos o estado quando o botão é pressionado:
const [flashMode, setFlashMode] = React.useState('off') const __handleFlashMode = () => { if (flashMode === 'on') { setFlashMode('off') } else if (flashMode === 'off') { setFlashMode('on') } else { setFlashMode('auto') } }
E então adicionamos adereços FlashMode:
<Camera flashMode={flashMode} style={{flex: 1}} ref={(r) => { camera = r }} ></Camera>
Como acessar a câmera frontal e traseira
Vamos adicionar um botão que alterna entre a câmera traseira e frontal.
Podemos obter o tipo de câmera padrão diretamente do módulo da câmera como abaixo:
const [cameraType, setCameraType] = React.useState(Camera.Constants.Type.back)
Adicionar type
adereços como este:
<Camera type={cameraType} flashMode={flashMode} style={{flex: 1}} ref={(r) => { camera = r }} ></Camera>
E adicione o botão de troca:
<TouchableOpacity onPress={__switchCamera} style={{ marginTop: 20, borderRadius: '50%', height: 25, width: 25 }} > <Text style={{ fontSize: 20 }} > {cameraType === 'front' ? '🤳' : '📷'} </Text></TouchableOpacity>
E mudar a função:
const __switchCamera = () => { if (cameraType === 'back') { setCameraType('front') } else { setCameraType('back') } }
Aqui está o resultado:
Você pode encontrar o código-fonte completo em GitHub.
Empacotando
Em geral, Expo é uma ferramenta incrível que pode economizar muito tempo. Ele ajuda você a começar a construir diretamente e evita o trabalho de configuração do ambiente.
Às vezes, você pode querer construir uma extensão nativa e lidar com o uso de recursos nativos de sua própria maneira. Neste caso, eu recomendo usar o reagir nativo CLI para que você possa modificar e brincar com o código nativo facilmente.
Olá, meu nome é Said Hayani. eu criei subscribi.io para ajudar criadores, blogueiros e influenciadores a aumentar seu público por meio do boletim informativo.
Junte-se ao meu Lista de correio se você estiver interessado em ler mais sobre React Native.