Kako stvoriti aplikaciju kamere s Expo i React Native

Ako niste upoznati s expoom, klijent vam pomaže u izradi React Native aplikacija s manje složenosti izrade. Također vam pomaže u suočavanju sa stresom instaliranja i postavljanja vašeg okruženja za pokretanje React Nativea.

U ovom uputstvu izradit ćemo jednostavnu aplikaciju za kameru u kojoj korisnik može fotografirati, vidjeti preglede svojih slika, koristiti način bljeskalice i prebacivati ​​se između prednje i stražnje kamere.

Preduvjeti

Expo ne zahtijeva mnogo za početak izrade vaše prve React Native aplikacije. Ovdje o dokumentima možete saznati više o instaliranju expo-a i expo-cli-a.

Napomena: u ovom uputstvu koristit ću macOS i iOS. Možete koristiti i Android, u ovom trenutku nema velike razlike kada se koristi expo.

Možete globalno instalirati expo i expo-cli pokretanjem sljedeće naredbe:

npm install --global expo-cli

Expo za pokretanje zahtijeva Nodejs. Najnoviju verziju možete pokrenuti na službenoj web stranici ovdje.

Početak rada

Nakon što instalirate Expo i Nodejs, naredbom u nastavku možete započeti pokretanje novog Expo projekta:

expo init expo-camera-app

Kako instalirati pakete i pokrenuti aplikaciju

Expo nam nudi klijentsku aplikaciju u kojoj možemo pokrenuti i vidjeti pregled aplikacije koju gradimo. Dostupno je za preuzimanje u App Storeu i Google Playu.

Ovo je sučelje aplikacije.

Kako pokrenuti izložbeni projekt

Idite u direktorij aplikacija i pokrenite aplikaciju.

cd expo-camera-app 

Bit će vam postavljeno nekoliko pitanja za odabir zadanog predloška aplikacije. U ovom uputstvu jednostavno odabiremo praznu opciju (TypeScript), ali opet možete odabrati ono što vam odgovara.

Pokrenite aplikaciju

Nakon pokretanja projekta, aplikaciju možemo pokrenuti s expo run

Ovo će otvoriti prozor u vašem pregledniku u kojem možete vidjeti zapisnike. Također će generirati QR kôd koji možete skenirati za pokretanje aplikacije na uređaju.

Dobra stvar kod expoa je što ne morate instalirati i konfigurirati simulatore za pokretanje aplikacije. I dalje vam daje mogućnost pokretanja expo-a na simulatoru, ali simulator morate instalirati i konfigurirati sami.

Natrag na našu aplikaciju. Pod pretpostavkom da ste uspješno pokrenuli aplikaciju na uređaju, ovo će biti zadani zaslon:

Otvorite direktorij aplikacija u vašem omiljenom uređivaču koda. Koristim VS kod.

Izgled App.tsxće izgledati ovako:

import {StatusBar} from 'expo-status-bar' import React from 'react' import {StyleSheet, Text, View} from 'react-native' export default function App() { return (  Open up App.tsx to start working on your app!   ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' } }) 

Kako stvoriti korisničko sučelje

Nakon pokretanja projekta, vrijeme je da započnete s izradom korisničkog sučelja.

Instalirajte expo-kameru

Sljedeći je korak instaliranje expo-kamere, poput ove:

expo install expo-camera

Stvorit ćemo jednostavno korisničko sučelje koje će omogućiti korisniku da započne postupak korištenja kamere.

import {StatusBar} from 'expo-status-bar' import React from 'react' import {StyleSheet, Text, View, TouchableOpacity} from 'react-native' export default function App() { return (     Take picture      ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' } }) 

Jednostavno je korisničko sučelje: uvozimo TouchableOpacitygumb i napravimo jednostavan stil. Ako se pitate kako styling funkcionira u React Nativeu, ovdje možete pogledati moja dva članka:

  • Stiliziranje u React Native
  • Demistifikacija Flexboxa u React Nativeu

Sada moramo koristiti useStatekuku za upravljanje stanjem i prikaz prikaza kamere kad korisnik pritisne gumb za snimanje .

   Take picture  
 const [startCamera,setStartCamera] = React.useState(false) const __startCamera = ()=>{ }

Dvije su važne stvari koje moramo učiniti kada korisnik pritisne gumb:

  • Zatražite dopuštenje za pristup kameri. U mobilnom razvoju pristup mnogim izvornim API-jevima i mobilnim značajkama često je ograničen korisničkim dozvolama i privatnošću. To je samo nešto na što se morate naviknuti pri razvoju mobilnih aplikacija.
  • Change the state and present the camera.

Let's import the camera module from expo-camera with this command:

import {Camera} from 'expo-camera'

And add the camera view, like this:

  { camera = r }} >

We can use ref to access the camera's methods:

let camera: Camera

When the take picture button is pressed the __startCamera function will be called:

 const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if(status === 'granted'){ // do something }else{ Alert.alert("Access denied") }

The function will ask for permission first. If the user grant access to the camera, we can proceed and open the camera. If not, we show a simple alert.

Add the camera component

Let's display the camera when the user grants access to the device's camera.

 const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if (status === 'granted') { // start the camera setStartCamera(true) } else { Alert.alert('Access denied') } }

We have to make some changes to the UI and add a conditional rendering. We display the camera only when the user requests it, otherwise we display the default screen.

 {startCamera ? (  { camera = r }} > ) : (    Take picture    )}

Cool, now we need to add a button so we can take the actual picture.

Add the capture button

This is a simple View inside the camera view that has an absolute position. So we make sure that it is always on the top of the camera.

How to take a picture

The app should take a picture when capture button is pressed. That function will look like the below:

 const __takePicture = async () => { if (!camera) return const photo = await camera.takePictureAsync() }

First, we check that we have access to the Camera component using ref:

 if (!camera) return // if the camera is undefined or null, we stop the function execution

Then we take the picture by calling the takePictureAsync method. It returns a promise and an object that contains the picture's details. The result will look like this:

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

We are only interested in the Picture URL uri. After we take a picture, we have to show the photo preview and hide the camera view. To do that we will use two hooks to change the state:

 const [previewVisible, setPreviewVisible] = useState(false) const [capturedImage, setCapturedImage] = useState(null)
 const __takePicture = async () => { if (!camera) return const photo = await camera.takePictureAsync() console.log(photo) setPreviewVisible(true) setCapturedImage(photo) }
  • setPreviewVisible to show the preview
  • setCapturedImage(photo) to store the object result

Then we display the preview like this:

 {previewVisible && capturedImage ? (  ) : (  { camera = r }} >         )}

The CameraPreview component looks like this:

const CameraPreview = ({photo}: any) => { console.log('sdsfds', photo) return (    ) }

And the result looks like this:

How to re-take a picture

We can add some buttons to the preview that will allow the user to perform more actions. For example, they could re-take the photo or save it.

Add the savePhoto and retakePicture props to the CameraPreview component like this:

When the Re-take button is pressed, we will have to hide the preview, remove the current picture, and show the camera again. Do that with the following code:

 const __retakePicture = () => { setCapturedImage(null) setPreviewVisible(false) __startCamera() }

How to add other options – back camera, flash, and more

expo-camra offers many options for customizing the camera, like FlashMode, setting the Camera type (front/back), zooming, and so on.

How to add FlashMode

Let's add an option so the user can turn FlashMode on and off:

We simply create a small button to switch off/on the flash, like this:

   ⚡️  

And we just change the state when the button is pressed:

 const [flashMode, setFlashMode] = React.useState('off') const __handleFlashMode = () => { if (flashMode === 'on') { setFlashMode('off') } else if (flashMode === 'off') { setFlashMode('on') } else { setFlashMode('auto') } }

And then we add FlashMode props:

  { camera = r }} >

How to access the front and the back camera

We will add a button that switches between the back and front camera.

We can get the default camera type directly from the camera module like below:

 const [cameraType, setCameraType] = React.useState(Camera.Constants.Type.back)

Add type props like this:

  { camera = r }} >

And add the switch button:

  {cameraType === 'front' ? '?' : '?'}  

And switch function:

 const __switchCamera = () => { if (cameraType === 'back') { setCameraType('front') } else { setCameraType('back') } }

Here is the result:

You can find the full source code on GitHub.

Wrapping up

In general, Expo is an amazing tool that can save you a lot of time. It helps you start building directly and saves you the pain of environment setup.

Ponekad ćete možda htjeti izgraditi izvorno proširenje i rukovati se matičnim značajkama na svoj način. U ovom bih slučaju preporučio upotrebu CLI-a koji reagira nativno, tako da možete lako mijenjati i igrati se s matičnim kodom.

Bok, moje ime je Said Hayani. Stvorio sam subscribi.io kako bih pomogao tvorcima, blogerima i influencerima da povećaju svoju publiku putem biltena.

Pridružite se mojoj mailing listi ako vas zanima više o React Native.