كيفية إنشاء تطبيق كاميرا باستخدام Expo و React Native

إذا لم تكن على دراية بـ expo ، فهو عميل يساعدك في إنشاء تطبيقات 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 للتنزيل.

هذه هي واجهة التطبيق.

كيف تبدأ مشروع المعرض

انتقل إلى دليل التطبيق وقم بتشغيل التطبيق.

cd expo-camera-app 

سيُطلب منك بعض الأسئلة لتحديد النموذج الافتراضي للتطبيق. في هذا البرنامج التعليمي ، نختار ببساطة خيارًا فارغًا (TypeScript) ، ولكن مرة أخرى لك مطلق الحرية في اختيار ما هو مناسب لك.

قم بتشغيل التطبيق

بعد تمهيد المشروع ، يمكننا تشغيل التطبيق باستخدام expo run

سيؤدي هذا إلى فتح نافذة في متصفحك حيث يمكنك رؤية السجلات. سيُنشئ أيضًا رمز الاستجابة السريعة الذي يمكنك مسحه ضوئيًا لتشغيل التطبيق على جهازك.

الشيء الجيد في 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 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 = ()=>{ }

هناك شيئان مهمان يتعين علينا القيام به عندما يضغط المستخدم على الزر:

  • اطلب الإذن للوصول إلى الكاميرا. في تطوير الأجهزة المحمولة ، غالبًا ما يتم تقييد الوصول إلى العديد من واجهات برمجة التطبيقات الأصلية وميزات الجوال من خلال أذونات المستخدم والخصوصية. إنه مجرد شيء يجب أن تعتاد عليه عند تطوير تطبيقات الهاتف المحمول.
  • تغيير الحالة وتقديم الكاميرا.

دعنا نستورد وحدة الكاميرا من expo-cameraهذا الأمر:

import {Camera} from 'expo-camera'

وإضافة عرض الكاميرا ، مثل هذا:

  { camera = r }} >

يمكننا استخدامها refللوصول إلى طرق الكاميرا:

let camera: Camera

عند take pictureالضغط على الزر ، __startCameraسيتم استدعاء الوظيفة:

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

ستطلب الوظيفة الإذن أولاً. إذا منح المستخدم حق الوصول إلى الكاميرا ، فيمكننا المتابعة وفتح الكاميرا. إذا لم يكن الأمر كذلك ، فإننا نعرض تنبيهًا بسيطًا.

أضف مكون الكاميرا

دعنا نعرض الكاميرا عندما يمنح المستخدم حق الوصول إلى كاميرا الجهاز.

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

يتعين علينا إجراء بعض التغييرات على واجهة المستخدم وإضافة عرض شرطي. نعرض الكاميرا فقط عندما يطلبها المستخدم ، وإلا فإننا نعرض الشاشة الافتراضية.

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

رائع ، نحتاج الآن إلى إضافة زر حتى نتمكن من التقاط الصورة الفعلية.

أضف زر الالتقاط

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 المتفاعل الأصلي حتى تتمكن من التعديل واللعب بالرمز الأصلي بسهولة.

مرحبا اسمي سعيد حياني. لقد أنشأت subscribi.io لمساعدة المبدعين والمدونين والمؤثرين على زيادة جمهورهم من خلال النشرة الإخبارية.

انضم إلى القائمة البريدية الخاصة بي إذا كنت مهتمًا بقراءة المزيد حول React Native.