Πώς να δημιουργήσετε μια εφαρμογή κάμερας με το Expo και το React Native

Εάν δεν είστε εξοικειωμένοι με την έκθεση, είναι ένας πελάτης που σας βοηθά να δημιουργήσετε εφαρμογές React Native με λιγότερη πολυπλοκότητα κατασκευής. Σας βοηθά επίσης να αντιμετωπίσετε το άγχος της εγκατάστασης και ρύθμισης του περιβάλλοντός σας για την εκτέλεση του React Native.

Σε αυτό το σεμινάριο, θα δημιουργήσουμε μια απλή εφαρμογή κάμερας στην οποία ο χρήστης μπορεί να τραβήξει φωτογραφίες, να δει προεπισκοπήσεις των φωτογραφιών του, να χρησιμοποιήσει τη λειτουργία φλας και να εναλλάξει μεταξύ της μπροστινής και της πίσω κάμερας.

Προαπαιτούμενα

Το Expo δεν απαιτεί πολλά για να αρχίσει να δημιουργεί την πρώτη σας εφαρμογή React Native. Μπορείτε να μάθετε περισσότερα σχετικά με την εγκατάσταση του expo και του expo-cli εδώ στα έγγραφα.

Σημείωση: σε αυτό το σεμινάριο, θα χρησιμοποιώ macOS και iOS. Μπορείτε επίσης να χρησιμοποιήσετε το Android, δεν υπάρχει μεγάλη διαφορά όταν χρησιμοποιείτε την έκθεση σε αυτό το σημείο.

Μπορείτε να εγκαταστήσετε το expo και το expo-cli παγκοσμίως εκτελώντας την ακόλουθη εντολή:

npm install --global expo-cli

Το Expo απαιτεί Nodejs για να τρέξει. Μπορείτε να εκτελέσετε την τελευταία έκδοση στον επίσημο ιστότοπο εδώ.

Ξεκινώντας

Αφού εγκαταστήσετε το Expo και το Nodejs, μπορείτε να ξεκινήσετε την εκκίνηση ενός νέου έργου Expo με την παρακάτω εντολή:

expo init expo-camera-app

Πώς να εγκαταστήσετε τα πακέτα και να εκτελέσετε την εφαρμογή

Η Expo μας παρέχει μια εφαρμογή πελάτη όπου μπορούμε να τρέξουμε και να δούμε την προεπισκόπηση της εφαρμογής που χτίζουμε. Είναι διαθέσιμο τόσο στο App Store όσο και στο Google Play για λήψη.

Αυτή είναι η διεπαφή της εφαρμογής.

Πώς να ξεκινήσετε ένα έργο expo

Μεταβείτε στον κατάλογο εφαρμογών και εκτελέστε την εφαρμογή.

cd expo-camera-app 

Θα σας ζητηθούν μερικές ερωτήσεις για να επιλέξετε το προεπιλεγμένο πρότυπο για την εφαρμογή. Σε αυτό το σεμινάριο επιλέγουμε απλώς μια κενή (TypeScript) επιλογή, αλλά και πάλι είστε ελεύθεροι να επιλέξετε τι είναι κατάλληλο για εσάς.

Εκτελέστε την εφαρμογή

Μετά την εκκίνηση του έργου, μπορούμε να εκτελέσουμε την εφαρμογή με expo run

Αυτό θα ανοίξει ένα παράθυρο στο πρόγραμμα περιήγησής σας όπου μπορείτε να δείτε τα αρχεία καταγραφής. Θα δημιουργήσει επίσης έναν κωδικό QR που μπορείτε να σαρώσετε για να εκτελέσετε την εφαρμογή στη συσκευή σας.

Το καλό με την έκθεση είναι ότι δεν χρειάζεται να εγκαταστήσετε και να διαμορφώσετε τους προσομοιωτές για να εκτελέσετε την εφαρμογή. Σας δίνει ακόμα την επιλογή να εκτελέσετε το expo στον προσομοιωτή, αλλά πρέπει να εγκαταστήσετε και να διαμορφώσετε τον προσομοιωτή μόνοι σας.

Επιστροφή στην εφαρμογή μας. Υποθέτοντας ότι έχετε εκτελέσει με επιτυχία την εφαρμογή στη συσκευή, αυτή θα είναι η προεπιλεγμένη οθόνη:

Ανοίξτε τον κατάλογο εφαρμογών στον αγαπημένο σας επεξεργαστή κώδικα. Χρησιμοποιώ VS Code.

Η App.tsxεμφάνιση θα μοιάζει με αυτό:

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' } }) 

Πώς να δημιουργήσετε το περιβάλλον εργασίας χρήστη

Αφού εκτελέσετε το έργο, τώρα ήρθε η ώρα να αρχίσετε να δημιουργείτε κάποιο περιβάλλον χρήστη

Εγκαταστήστε την εκθετική κάμερα

Το επόμενο βήμα είναι να εγκαταστήσετε την κάμερα-expo, ως εξής:

expo install expo-camera

Θα δημιουργήσουμε ένα απλό περιβάλλον εργασίας χρήστη που θα επιτρέπει στον χρήστη να ξεκινήσει τη διαδικασία χρήσης της κάμερας.

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' } }) 

Είναι ένα απλό περιβάλλον χρήστη: εισάγουμε TouchableOpacityγια το κουμπί και κάνουμε απλό στυλ Εάν αναρωτιέστε πώς λειτουργεί το στυλ στο React Native, μπορείτε να δείτε τα δύο άρθρα μου εδώ:

  • Στυλ στο React Native
  • Απομυθοποίηση Flexbox στο React Native

Τώρα πρέπει να χρησιμοποιήσουμε ένα useStateάγκιστρο για να διαχειριστούμε την κατάσταση και να εμφανίσουμε την προβολή της κάμερας όταν ο χρήστης πατήσει το κουμπί λήψης φωτογραφίας .

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

Υπάρχουν δύο σημαντικά πράγματα που πρέπει να κάνουμε όταν ο χρήστης πατήσει το κουμπί:

  • Ζητήστε άδεια για πρόσβαση στην κάμερα. Στην ανάπτυξη για κινητά, η πρόσβαση σε πολλά εγγενή API και λειτουργίες για κινητά περιορίζεται συχνά από τα δικαιώματα του χρήστη και το απόρρητο. Είναι κάτι που πρέπει να συνηθίσετε κατά την ανάπτυξη εφαρμογών για κινητά.
  • 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.

Μερικές φορές μπορεί να θέλετε να δημιουργήσετε μια εγγενή επέκταση και να χειριστείτε χρησιμοποιώντας εγγενείς λειτουργίες με τον δικό σας τρόπο. Σε αυτήν την περίπτωση, θα συνιστούσα να χρησιμοποιήσετε το αντιδραστικό CLI, ώστε να μπορείτε εύκολα να τροποποιήσετε και να παίξετε με εγγενή κώδικα.

Γεια, το όνομά μου είναι Said Hayani. Δημιούργησα το subscribi.io για να βοηθήσω τους δημιουργούς, τους μπλόγκερ και τους επηρεαστές να αυξήσουν το κοινό τους μέσω του ενημερωτικού δελτίου.

Εγγραφείτε στη λίστα αλληλογραφίας μου εάν ενδιαφέρεστε να διαβάσετε περισσότερα για το React Native