<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: thaind0</title>
    <description>The latest articles on DEV Community by thaind0 (@thaind0).</description>
    <link>https://dev.to/thaind0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1107473%2F57c0bd1b-4029-4f37-9651-900b616cb171.png</url>
      <title>DEV Community: thaind0</title>
      <link>https://dev.to/thaind0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thaind0"/>
    <language>en</language>
    <item>
      <title>React Native Vision Camera: Installation, Picture Capture, and Video Recording</title>
      <dc:creator>thaind0</dc:creator>
      <pubDate>Sat, 24 Jun 2023 20:48:53 +0000</pubDate>
      <link>https://dev.to/thaind0/react-native-vision-camera-installation-picture-capture-and-video-recording-5g5j</link>
      <guid>https://dev.to/thaind0/react-native-vision-camera-installation-picture-capture-and-video-recording-5g5j</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/react-native-camera/react-native-camera" rel="noopener noreferrer"&gt;React-Native-Camera&lt;/a&gt;, while once popular and powerful, has been deprecated, leaving developers in search of an alternative. Enter VisionCamera, a fully featured camera library developed by &lt;a href="https://github.com/mrousavy" rel="noopener noreferrer"&gt;mrousavy&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In this series of articles, we will explore the power and versatility of VisionCamera. From installation and basic usage to more advanced features such as picture capture, video recording, and even face detection, this guide will equip you with the knowledge and skills to leverage VisionCamera to its fullest potential in your React Native applications. So let's dive in and unlock the possibilities of VisionCamera together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 1: Setting up Vision Camera
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 Installing react-native-vision-camera:
&lt;/h3&gt;

&lt;p&gt;Install &lt;em&gt;react-native-vision-camera&lt;/em&gt; with yarn:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add react-native-vision-camera&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And make sure to install pod dependencies:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd ios &amp;amp;&amp;amp; pod install &amp;amp;&amp;amp; cd ..&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 Configuring iOS:
&lt;/h3&gt;

&lt;p&gt;Open your project's &lt;code&gt;Info.plist&lt;/code&gt; and add the following lines inside the outermost &lt;code&gt;&amp;lt;dict&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;key&amp;gt;NSCameraUsageDescription&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;$(PRODUCT_NAME) needs access to your Camera.&amp;lt;/string'&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;$(PRODUCT_NAME)&lt;/code&gt; is a variable of your application name&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3 Configuring Android:
&lt;/h3&gt;

&lt;p&gt;Open your project's &lt;code&gt;AndroidManifest.xml&lt;/code&gt; and add the following lines inside the &lt;code&gt;&amp;lt;manifest&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;uses-permission android:name="android.permission.CAMERA" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.4 Getting/Requesting Permissions:
&lt;/h3&gt;

&lt;p&gt;To find out if a user has granted or denied:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const cameraPermission = await Camera.getCameraPermissionStatus()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get permission to use Camera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const newCameraPermission = await Camera.requestCameraPermission()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if user denied, user has go to settings and allow camera permission manually. There for we should double check the camera permission and open settings if user is not granted.&lt;br&gt;
So this is the full permission handle code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {Alert, Linking} from 'react-native';
import {Camera} from 'react-native-vision-camera';

export const requestCameraPermission = async () =&amp;gt; {
  const cameraPermission = await Camera.requestCameraPermission();

  if (cameraPermission !== 'authorized') {
    Alert.alert(
      'You need to allow camera permission.',
      'Please go to Settings and allow camera permission',
      [
        {
          text: 'Open Settings',
          onPress: Linking.openSettings,
        },
      ],
    );
  }

  return cameraPermission;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Section 2: Picture Capture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1: Camera setup
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Camera devices
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Camera devices are the physical (or "virtual") devices that can be used to record videos or capture photos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To get a camera device, we use the &lt;code&gt;useCameraDevices&lt;/code&gt; hook and specific with camera could be used&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const devices = useCameraDevices();

  const device = devices.back;

  if (!device) {
    return &amp;lt;ActivityIndicator /&amp;gt;;
  }

return (
   &amp;lt;Camera
     style={StyleSheet.absoluteFill}
     device={device}
     isActive
   /&amp;gt;
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  camera ref
&lt;/h4&gt;

&lt;p&gt;we use ref to access the photo capture function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const camera = useRef&amp;lt;Camera&amp;gt;(null);
/*...*/

return (
   &amp;lt;Camera
    style={StyleSheet.absoluteFill}
    device={device}
    isActive
    // Add this
    ref={camera}
    photo
   /&amp;gt;
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  CameraWrapper component
&lt;/h4&gt;

&lt;p&gt;I added this component with the aim of being able to easily switch between showing the camera as a separate screen or as a modal. You can skip this component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// CameraWrapper.tsx
import React from 'react';
import {ActivityIndicator, Modal, SafeAreaView, StyleSheet} from 'react-native';

interface CameraWrapperProps {
  isActive: boolean;
  onInactive?: () =&amp;gt; void;
  children: React.ReactNode;
  loading?: boolean;
}

const CameraWrapper = (props: CameraWrapperProps) =&amp;gt; {
  const {isActive, onInactive, children, loading} = props;

  return (
    &amp;lt;Modal
      visible={isActive}
      onRequestClose={onInactive}
      style={styles.container}&amp;gt;
      &amp;lt;SafeAreaView style={StyleSheet.absoluteFill}&amp;gt;
        {loading ? &amp;lt;ActivityIndicator style={styles.loading} /&amp;gt; : children}
      &amp;lt;/SafeAreaView&amp;gt;
    &amp;lt;/Modal&amp;gt;
  );
};

export default CameraWrapper;

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  loading: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Taking picture:
&lt;/h3&gt;

&lt;p&gt;To taking a picture use the camera ref:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const photo = await camera.current.takePhoto()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Capture button
&lt;/h4&gt;

&lt;p&gt;To do the image capture, I write a component that manages the capture. This is the photo button that receives the props as the camera ref and a callback function that returns the captured image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, {RefObject, useCallback} from 'react';
import {StyleSheet, TouchableOpacity, View, ViewProps} from 'react-native';
import {Camera, PhotoFile} from 'react-native-vision-camera';

interface CaptureButtonProps extends ViewProps {
  camera: RefObject&amp;lt;Camera&amp;gt;;
  onMediaCaptured: (file: PhotoFile) =&amp;gt; void;
}

const CaptureButton = (props: CaptureButtonProps) =&amp;gt; {
  const {camera, onMediaCaptured, style, ...rest} = props;

  const onPress = useCallback(async () =&amp;gt; {
    const photo = await camera.current?.takePhoto();
    onMediaCaptured(photo!);
  }, [camera, onMediaCaptured]);

  return (
    &amp;lt;TouchableOpacity
      {...rest}
      onPress={onPress}
      style={[styles.captureButton, style]}&amp;gt;
      &amp;lt;View style={styles.captureButtonInner} /&amp;gt;
    &amp;lt;/TouchableOpacity&amp;gt;
  );
};

export default CaptureButton;

const styles = StyleSheet.create({
  captureButton: {
    width: 80,
    height: 80,
    borderRadius: 40,
    padding: 4,
    borderWidth: 2,
    borderStyle: 'dotted',
    borderColor: 'white',
  },
  captureButtonInner: {
    flex: 1,
    borderRadius: 40,
    backgroundColor: 'white',
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And use it inside our TakePicture component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const onPhotoCaptured = useCallback((file: PhotoFile) =&amp;gt; {
    console.log(file);
  }, []);

  return (
    &amp;lt;CameraWrapper isActive={isActive} loading={!device} onInactive={onInactive}&amp;gt;
      &amp;lt;Camera
        ref={camera}
        style={StyleSheet.absoluteFill}
        device={device!}
        isActive={isActive}
        photo
      /&amp;gt;
      &amp;lt;CaptureButton
        camera={camera}
        style={styles.captureButton}
        onMediaCaptured={onPhotoCaptured}
      /&amp;gt;
    &amp;lt;/CameraWrapper&amp;gt;
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Console result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmhbh0d7zs19ua13bsbg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmhbh0d7zs19ua13bsbg4.png" alt="Captured picture log" width="800" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 Preview captured picture
&lt;/h3&gt;

&lt;p&gt;We can use react-native's Image to display the result of our capture feature&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, {useMemo} from 'react';
import {Button, Image, Modal, SafeAreaView, StyleSheet} from 'react-native';

interface MediaPreviewProps {
  mediaPath?: string;
  onInactive?: () =&amp;gt; void;
}

const MediaPreview = ({mediaPath, onInactive}: MediaPreviewProps) =&amp;gt; {
  const source = useMemo(() =&amp;gt; ({uri: mediaPath}), [mediaPath]);

  return (
    &amp;lt;Modal visible={!!mediaPath} onRequestClose={onInactive}&amp;gt;
      &amp;lt;SafeAreaView style={[StyleSheet.absoluteFill]}&amp;gt;
        &amp;lt;Image source={source} style={StyleSheet.absoluteFill} /&amp;gt;
        &amp;lt;Button onPress={onInactive} title="Close" /&amp;gt;
      &amp;lt;/SafeAreaView&amp;gt;
    &amp;lt;/Modal&amp;gt;
  );
};

export default MediaPreview;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.4 Zooming
&lt;/h3&gt;

&lt;p&gt;To let user to zoom with native pinch to zoom gesture you can enable with the &lt;a href="https://www.react-native-vision-camera.com/docs/api/interfaces/CameraProps#enablezoomgesture" rel="noopener noreferrer"&gt;enableZoomGesture&lt;/a&gt; prop&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &amp;lt;Camera
        ref={camera}
        style={StyleSheet.absoluteFill}
        device={device!}
        isActive={isActive}
        photo
        // for zooming
        enableZoomGesture
      /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.5 Focusing
&lt;/h3&gt;

&lt;p&gt;To focus the camera to a specific point, simply use the Camera's &lt;a href="https://www.react-native-vision-camera.com/docs/api/classes/Camera#focus" rel="noopener noreferrer"&gt;focus(...)&lt;/a&gt; function with &lt;code&gt;onTouchStart&lt;/code&gt; of any View component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &amp;lt;Camera
        ref={camera}
        style={StyleSheet.absoluteFill}
        device={device!}
        isActive={isActive}
        photo
        // For focusing
        onTouchStart={handleFocus}
        enableZoomGesture
      /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Handling focus touch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const handleFocus = useCallback(
    async ({nativeEvent}: GestureResponderEvent) =&amp;gt; {
      await camera?.current?.focus({
        x: Math.round(nativeEvent.pageX),
        y: Math.round(nativeEvent.pageX),
      });
    },
    [],
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Section 3: Recording Videos
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Record audio permissions (Optional):
&lt;/h3&gt;

&lt;p&gt;If you want to record audio on recording video, you have to update your application's manifests&lt;/p&gt;

&lt;h5&gt;
  
  
  iOS
&lt;/h5&gt;

&lt;p&gt;Open your project's &lt;code&gt;Info.plist&lt;/code&gt; and add the following lines inside the outermost &lt;code&gt;&amp;lt;dict&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;key&amp;gt;NSMicrophoneUsageDescription&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;$(PRODUCT_NAME) needs access to your Microphone.&amp;lt;/string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Android
&lt;/h4&gt;

&lt;p&gt;Open your project's &lt;code&gt;AndroidManifest.xml&lt;/code&gt; and add the following lines inside the &lt;code&gt;&amp;lt;manifest&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;uses-permission android:name="android.permission.RECORD_AUDIO" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and we also have the &lt;code&gt;requestMicrophonePermission&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {Alert, Linking} from 'react-native';
import {Camera} from 'react-native-vision-camera';

export const requestMicrophonePermission = async () =&amp;gt; {
  const microphonePermission = await Camera.requestMicrophonePermission();

  if (microphonePermission !== 'authorized') {
    Alert.alert(
      'You need to allow microphone permission.',
      'Please go to Settings and allow microphone permission',
      [
        {
          text: 'Open Settings',

          onPress: Linking.openSettings,
        },
      ],
    );
  }

  return microphonePermission;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Update the Camera component:
&lt;/h3&gt;

&lt;p&gt;In this section I will copy the component of the photography section, which means that video recording will also have full features like focus or zoom. For Camera to record video add &lt;code&gt;video&lt;/code&gt; prop and if you want to record audio add &lt;code&gt;audio&lt;/code&gt; prop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &amp;lt;Camera
        ref={camera}
        style={StyleSheet.absoluteFill}
        device={device!}
        isActive={isActive}
        onTouchStart={handleFocus}
        enableZoomGesture
        photo
        video
        audio // optional
      /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Hold Capture button to start recording video
&lt;/h3&gt;

&lt;p&gt;To start recording, the user will hold down the capture button. The button will turn red indicating the recording status and when the user clicks this button again, the video recording will end.&lt;br&gt;
I also updated the onMediaCaptured callback to add the VideoFile data type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// import

interface CaptureButtonProps extends ViewProps {
  camera: RefObject&amp;lt;Camera&amp;gt;;
  onMediaCaptured: (
    media: PhotoFile | VideoFile,
    type: 'photo' | 'video',
  ) =&amp;gt; void;
}

const CaptureButton = (props: CaptureButtonProps) =&amp;gt; {
  const {camera, onMediaCaptured, style, ...rest} = props;
  const [isRecording, setIsRecording] = React.useState(false);

  const innerStyle = useMemo(
    () =&amp;gt; ({
      backgroundColor: isRecording ? 'red' : 'white',
    }),
    [isRecording],
  );

  const takePhoto = useCallback(async () =&amp;gt; {
    if (isRecording) {
      setIsRecording(false);
      return camera.current?.stopRecording();
    }
    const photo = await camera.current?.takePhoto();
    onMediaCaptured(photo!, 'photo');
  }, [camera, onMediaCaptured, isRecording]);

  const startRecordingVideo = useCallback(async () =&amp;gt; {
    setIsRecording(true);
    return camera.current?.startRecording({
      onRecordingFinished: video =&amp;gt; onMediaCaptured(video, 'video'),
      onRecordingError: error =&amp;gt; console.error(error),
    });
  }, [camera, onMediaCaptured]);

  return (
    &amp;lt;TouchableOpacity
      {...rest}
      style={[styles.captureButton, style]}
      onPress={takePhoto}
      onLongPress={startRecordingVideo}&amp;gt;
      &amp;lt;View style={[styles.captureButtonInner, innerStyle]} /&amp;gt;
    &amp;lt;/TouchableOpacity&amp;gt;
  );
};

export default CaptureButton;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4 Preview video
&lt;/h3&gt;

&lt;p&gt;We use &lt;a href="https://github.com/react-native-video/react-native-video" rel="noopener noreferrer"&gt;react-native-video&lt;/a&gt; to display the recorded video.&lt;/p&gt;

&lt;p&gt;Install it with yarn:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add react-native-video&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And make sure to install pod dependencies:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd ios &amp;amp;&amp;amp; pod install &amp;amp;&amp;amp; cd ..&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          &amp;lt;Video
            source={source}
            style={StyleSheet.absoluteFill}
            resizeMode="cover"
            posterResizeMode="cover"
            allowsExternalPlayback={false}
          automaticallyWaitsToMinimizeStalling={false}
            disableFocus={true}
            repeat={true}
            useTextureView={false}
            controls={false}
            playWhenInactive={true}
          /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Section 4: Saving the media
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Requesting Permissions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {Alert, Linking, PermissionsAndroid, Platform} from 'react-native';

export const requestSavePermission = async () =&amp;gt; {
  if (Platform.OS !== 'android') {
    return true;
  }

  const permission = PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;
  if (permission == null) {
    return false;
  }
  let hasPermission = await PermissionsAndroid.check(permission);
  if (!hasPermission) {
    const permissionRequestResult = await PermissionsAndroid.request(
      permission,
    );
    hasPermission = permissionRequestResult === 'granted';
  }
  if (!hasPermission) {
    Alert.alert(
      'You need to allow storage permission.',
      'Please go to Settings and allow storage permission',
      [
        {
          text: 'Open Settings',
          // On pressing the button, we will open the settings
          onPress: Linking.openSettings,
        },
      ],
    );
  }

  return hasPermission;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use &lt;a href="https://github.com/react-native-cameraroll/react-native-cameraroll" rel="noopener noreferrer"&gt;@react-native-camera-roll/camera-roll&lt;/a&gt; to saving media.&lt;/p&gt;

&lt;p&gt;Install it with yarn:&lt;br&gt;
&lt;code&gt;yarn add @react-native-camera-roll/camera-roll&lt;/code&gt;&lt;br&gt;
And make sure to install pod dependencies:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd ios &amp;amp;&amp;amp; pod install &amp;amp;&amp;amp; cd ..&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open your project's &lt;code&gt;Info.plist&lt;/code&gt; and add the following lines inside the outermost &lt;code&gt;&amp;lt;dict&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;key&amp;gt;NSPhotoLibraryUsageDescription&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;$(PRODUCT_NAME) needs access to your Photo Library.&amp;lt;/string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open your project's &lt;code&gt;AndroidManifest.xml&lt;/code&gt; and add &lt;code&gt;android:requestLegacyExternalStorage="true"&lt;/code&gt; to &lt;code&gt;application&lt;/code&gt; tag and the following inside &lt;code&gt;manifest&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const handleSave = useCallback(async () =&amp;gt; {
    setSaveStatus('saving');
    const hasPermission = await requestSavePermission();

    if (hasPermission) {
      await CameraRoll.save(`file://${mediaPath}`, {
        type,
      });
      setSaveStatus('saved');
    }
  }, [mediaPath, type]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;We have explored the power and versatility of VisionCamera as an alternative to the deprecated React-Native-Camera library. We have covered the installation process and basic configuration steps for both iOS and Android platforms. Additionally, we have discussed how to handle camera permissions and provided code examples for requesting and checking camera permissions.&lt;/p&gt;

&lt;p&gt;I hope that this series of articles has provided you with a comprehensive understanding of VisionCamera and its capabilities. By leveraging VisionCamera, you can enhance your React Native applications with powerful camera features, such as picture capture and video recording. In the next article, we will dive deeper into customizing the camera interface by exploring options for zooming and configuring photo/video settings.&lt;/p&gt;

&lt;p&gt;Stay tuned for the next article, where we will explore custom zoom options and provide insights on configuring photo and video settings to further enhance your camera functionality.&lt;/p&gt;

&lt;p&gt;To access the complete source code and examples discussed in this series, please visit the GitHub repository: &lt;a href="https://github.com/thaind0/RnVisionCameraGuide" rel="noopener noreferrer"&gt;this&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.react-native-vision-camera.com" rel="noopener noreferrer"&gt;https://www.react-native-vision-camera.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mrousavy/react-native-vision-camera" rel="noopener noreferrer"&gt;https://github.com/mrousavy/react-native-vision-camera&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/react-native-video" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-native-video&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/@react-native-camera-roll/camera-roll" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@react-native-camera-roll/camera-roll&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>reactnative</category>
    </item>
  </channel>
</rss>
