Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Camera Access, Photo Capture, and Image Saving in React Native

Tech Oct 17 5

Setting Up Camera Functionality in React Native

Project Initialization

To begin, create a new React Native project with the folowing command:

npx react-native init CameraApp --version 0.70.6

Dependency Installation

Add the required packages to your project:

// package.json
"dependencies": {
 "@react-native-camera-roll/camera-roll": "^7.4.2",
 "react-native-vision-camera": "2.15.4"
}

Install the packages using:

yarn add @react-native-camera-roll/camera-roll
yarn add react-native-vision-camera@2.15.4

Android Configuration

Update the AndroidManifest.xml file to include camera permissions:

<manifest>
 <uses-permission android:name="android.permission.CAMERA" />
 <uses-permission android:name="android.permission.RECORD_AUDIO" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 
 <application
   android:requestLegacyExternalStorage="true"
   ...
 >
 </application>
</manifest>

iOS Configuration

Add camera permissions to Info.plist:

<key>NSCameraUsageDescription</key>
<string>App requires camera access to take photos</string>

<key>NSMicrophoneUsageDescription</key>
<string>App requires microphone access for camera functionality</string>

Camera Implementation

Here's the complete implementation for the camera functionality:

import { useCameraDevices, Camera } from 'react-native-vision-camera'
import React, { useRef, useEffect, useState } from 'react'
import { PermissionsAndroid, Text, View, Button, Alert, Platform } from 'react-native'
import { CameraRoll } from "@react-native-camera-roll/camera-roll"

const CameraComponent = () => {
 const cameraRef = useRef(null)
 const [cameraPermission, setCameraPermission] = useState(false)
 const [selectedDevice, setSelectedDevice] = useState(null)
 const [devices, setDevices] = useState([])

 useEffect(() => {
   initializeCamera()
 }, [])

 const initializeCamera = async () => {
   // Request camera permissions
   const granted = await PermissionsAndroid.request(
     PermissionsAndroid.PERMISSIONS.CAMERA,
     {
       title: 'Camera Access Required',
       message: 'This app needs to access your camera to take photos.',
       buttonNeutral: 'Ask Later',
       buttonNegative: 'Cancel',
       buttonPositive: 'OK',
     }
   )

   if (granted === PermissionsAndroid.RESULTS.GRANTED) {
     setCameraPermission(true)
     // Get available camera devices
     const availableDevices = useCameraDevices()
     setDevices(availableDevices)
     // Set default to back camera
     if (availableDevices.back) {
       setSelectedDevice(availableDevices.back)
     }
   } else {
     setCameraPermission(false)
   }
 }

 const switchCamera = () => {
   if (selectedDevice === devices.back) {
     setSelectedDevice(devices.front)
   } else {
     setSelectedDevice(devices.back)
   }
 }

 const capturePhoto = async () => {
   if (cameraRef.current && selectedDevice) {
     try {
       const capturedImage = await cameraRef.current.takePhoto()
       console.log('Photo captured:', capturedImage)
       saveToGallery(capturedImage)
     } catch (error) {
       console.error('Photo capture failed:', error)
     }
   }
 }

 const saveToGallery = async (image) => {
   const imagePath = Platform.OS === 'android' ? 'file://' + image.path : image.path
   
   CameraRoll.saveToCameraRoll(imagePath, 'photo')
     .then(() => {
       Alert.alert('Success', 'Photo saved to gallery')
     })
     .catch((error) => {
       Alert.alert('Error', 'Failed to save photo')
     })
 }

 return (
   <view flex:="" style="{{">
     {cameraPermission && selectedDevice ? (
       <view>
         <camera device="{selectedDevice}" height:="" isactive="{true}" photo="{true}" ref="{cameraRef}" style="{{" width:=""></camera>
         <button onpress="{capturePhoto}" title="Capture"></button>
         <button onpress="{switchCamera}" title="Switch Camera"></button>
       </view>
     ) : (
       <text>Camera permission not granted</text>
     )}
   </view>
 )
}

export default CameraComponent

Base64 Image Saving

For saving imagess from base64 strings:

import RNFS from 'react-native-fs';
import { CameraRoll } from '@react-native-camera-roll/camera-roll';
import { Platform, PermissionsAndroid } from 'react-native';

const saveBase64Image = async (base64Image) => {
 const imageData = base64Image.split('data:image/png;base64,')[1]
 const timestamp = new Date().getTime()
 const fileName = `${timestamp}photo.png`
 
 if (Platform.OS === 'android') {
   const storagePath = `${RNFS.ExternalDirectoryPath}/${fileName}`
   
   await PermissionsAndroid.requestMultiple([
     PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
     PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE
   ])
   
   await RNFS.writeFile(storagePath, imageData, 'base64')
   await CameraRoll.saveToCameraRoll('file://' + storagePath)
 } else {
   const storagePath = `${RNFS.DocumentDirectoryPath}/${fileName}`
   await RNFS.writeFile(storagePath, imageData, 'base64')
   await CameraRoll.saveToCameraRoll(storagePath)
 }
}

export { saveBase64Image }

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.