Как делать снимки с помощью встроенной камеры expo React?

Я только начал использовать React Native с Expo, поэтому я немного смущен. Итак, я сделал компонент камеры, который импортировал на главный экран. Все выглядит хорошо. Но я не могу фотографировать. Я не могу щелкнуть значок привязки и сохранить изображение. Есть ли компонент, который я пропустил? Я разместил только класс CameraComponent ниже.

Camera.js

class CameraComponent extends Component {

  state = {
    hasCameraPermission: null,
    type: Camera.Constants.Type.back
  }

  async componentWillMount() {
    const { status } = await Permissions.askAsync(Permissions.CAMERA);
    this.setState({ hasCameraPermission: status === 'granted' })
  }

  render() {
    const { hasCameraPermission } = this.state

    if (hasCameraPermission === null) {
      return <View />
    }
    else if (hasCameraPermission === false) {
      return <Text> No access to camera</Text>
    }
    else {
      return (
        <View style = {{ flex: 1 }}>
          <Camera 
            style = {{ flex: 1, justifyContent: 'space-between' }}
            type = {this.state.type}
          >
            <Header
              searchBar
              rounded
              style = {{
                position: 'absolute',
                backgroundColor: 'transparent',
                left: 0,
                top: 0,
                right: 0,
                zIndex: 100,
                alignItems: 'center'
              }}
            >
              <View style = {{ flexDirection: 'row', flex: 4 }}>
                <Ionicons name = "md-camera" style = {{ color: 'white' }} />
                <Item style = {{ backgroundColor: 'transparent' }}>
                  <Icon name = "ios-search" style = {{ color: 'white', fontSize: 24, fontWeight: 'bold' }}></Icon>
                </Item>
              </View>

              <View style = {{ flexDirection: 'row', flex: 2, justifyContent: 'space-around' }}>
                <Icon name = "ios-flash" style = {{ color: 'white', fontWeight: 'bold' }} />
                <Icon
                  onPress = {() => {
                    this.setState({
                      type: this.state.type === Camera.Constants.Type.back ?                                        
                                            Camera.Constants.Type.front :
                                            Camera.Constants.Type.back
                    })
                  }}
                  name = "ios-reverse-camera"
                  style = {{ color: 'white', fontWeight: 'bold' }}
                />
              </View>
            </Header>

            <View style = {{ flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 30, marginBottom: 15, alignItems: 'flex-end' }}>
              <Ionicons name = "ios-map" style = {{ color: 'white', fontSize: 36 }}></Ionicons>
              <View></View>
              <View style = {{ alignItems: 'center' }}>
                <MaterialCommunityIcons name = "circle-outline"   // This is the icon which should take and save image
                  style = {{ color: 'white', fontSize: 100 }}
                ></MaterialCommunityIcons>
                <Icon name = "ios-images" style = {{ color: 'white', fontSize: 36 }} />
              </View>
            </View>
          </Camera>
        </View>
      )
    }
  }
}

export default CameraComponent;

Значок в центре круга должен автоматически сделать и сохранить изображение.

Умерло ли Create-React-App?
Умерло ли Create-React-App?
В этом документальном фильме React.dev мы исследуем, мертв ли Create React App (CRA) и какое будущее ждет этот популярный фреймворк React.
Освоение React Native: Пошаговое руководство для начинающих
Освоение React Native: Пошаговое руководство для начинающих
React Native - это популярный фреймворк с открытым исходным кодом, используемый для разработки мобильных приложений. Он был разработан компанией...
В чем разница между react native и react ?
В чем разница между react native и react ?
React и React Native - два популярных фреймворка для создания пользовательских интерфейсов, но они предназначены для разных платформ. React - это...
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
Хуки React: что это такое и как их использовать
Хуки React: что это такое и как их использовать
Хуки React - это мощная функция библиотеки React, которая позволяет разработчикам использовать состояние и другие возможности React без написания...
7
0
14 507
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы пытаетесь сделать это на реальном физическом устройстве? Снимать фото с помощью эмулятора не получится.

Я использую клиент expo на устройстве Android для запуска приложения. Я сканирую qr-код.

Arjun Kashyap 09.10.2018 05:31

Таким образом, вам нужно указать свой «значок круга», чтобы сделать снимок. Сначала я бы добавил ссылку на вашу камеру вот так

<Camera style = {{ flex: 1 }}
      ref = { (ref) => {this.camera = ref} }
      type = {this.state.type}>

затем создайте функцию, которая фактически сообщает вашему приложению сделать снимок:

 async snapPhoto() {       
    console.info('Button Pressed');
    if (this.camera) {
       console.info('Taking photo');
       const options = { quality: 1, base64: true, fixOrientation: true, 
       exif: true};
       await this.camera.takePictureAsync(options).then(photo => {
          photo.exif.Orientation = 1;            
           console.info(photo);            
           });     
     }
    }

Теперь сделайте так, чтобы на вашем значке была кнопка onPress (), чтобы сделать снимок. Я сделал что-то подобное.

<TouchableOpacity style = {styles.captureButton} onPress = {this.snapPhoto.bind(this)}>
                <Image style = {{width: 100, height: 100}} source = {require('../assets/capture.png')}          
                />
            </TouchableOpacity>

Вы также можете создать представление, которое отображает предварительный просмотр изображения или что-то подобное. В документации Expo есть довольно хороший пример начала работы. Обратите внимание, что Expo создает кешированную папку под названием «Камера», и именно там изначально находится изображение.

Документация для этого находится здесь: docs.expo.io/versions/latest/sdk/camera

jsog 25.05.2019 16:42

Вам нужно будет добавить ссылку в класс Camera, чтобы иметь возможность вызывать его функцию takePictureAsync в вашем собственном методе «handle».

cameraRef = React.createRef();

<Camera ref = {this.cameraRef}>...</Camera>

Не забывайте ".current" при вызове метода указанной камеры.

handlePhoto = async () => {
  if (this.cameraRef){
    let photo = await this.cameraRef.current.takePictureAsync();
    console.info(photo);
  }  
}

Затем просто вызовите свой метод «handle» на сенсорном элементе, действующем как кнопка фотосъемки.

<TouchableOpacity 
  style = {{width:60, height:60, borderRadius:30, backgroundColor:"#fff"}} 
  onPress = {this.handlePhoto} />

Вы должны увидеть фотографию, зарегистрированную в вашей консоли.

Ответ принят как подходящий

Вы можете использовать onPictureSaved при возврате асинхронной функции takePictureAsync, чтобы вы могли захватить объект фотографии:

  takePicture = () => {
      if (this.camera) {
          this.camera.takePictureAsync({ onPictureSaved: this.onPictureSaved });
      }
   };

  onPictureSaved = photo => {
      console.info(photo);
  } 

В представлении у вас будет компонент Camera, у которого есть ссылка:

<Camera style = {styles.camera} type = {this.state.type} ref = {(ref) => { this.camera = ref }} >

А также кнопка, которая будет вызывать функцию takePicture при нажатии:

<TouchableOpacity style = {styles.captureButton} onPress = {this.takePicture} />

Вы можете сделать это и в функциональном компоненте, используя ссылку, созданную с помощью React Hook. Вот пример, основанный на компоненте камеры expo SDK 38 https://docs.expo.io/versions/v38.0.0/sdk/camera/

import React, { useState, useEffect, useRef } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { Camera } from 'expo-camera';

export default function App() {
  const [hasPermission, setHasPermission] = useState(null);
  const [type, setType] = useState(Camera.Constants.Type.back);
  const ref = useRef(null)

  useEffect(() => {
    (async () => {
      const { status } = await Camera.requestPermissionsAsync();
      setHasPermission(status === 'granted');
    })();
  }, []);
  
  _takePhoto = async () => {
    const photo = await ref.current.takePictureAsync()
    console.debug(photo)
  }

  if (hasPermission === null) {
    return <View />;
  }
  if (hasPermission === false) {
    return <Text>No access to camera</Text>;
  }
  return (
    <View style = {{ flex: 1 }}>
      <Camera style = {{ flex: 1 }} type = {type} ref = {ref}>
        <View
          style = {{
            flex: 1,
            backgroundColor: 'transparent',
            flexDirection: 'row',
          }}>
          <TouchableOpacity
            style = {{
              flex: 0.1,
              alignSelf: 'flex-end',
              alignItems: 'center',
            }}
            onPress = {() => {
              setType(
                type === Camera.Constants.Type.back
                  ? Camera.Constants.Type.front
                  : Camera.Constants.Type.back
              );
            }}>
            <Text style = {{ fontSize: 18, marginBottom: 10, color: 'white' }}> Flip </Text>
          </TouchableOpacity>
          <TouchableOpacity
            onPress = {_takePhoto}
          >
            <Text>Snap Photo</Text>
          </TouchableOpacity>
        </View>
      </Camera>
    </View>
  );
}

Я не проверял, как выглядит пользовательский интерфейс для этого, но главное - использовать React.useRef и прикрепить ссылку к вашему компоненту <Camera/>. Затем вы можете вызвать ref.current.takePictureAsync, чтобы захватить и получить доступ к новому образу. Посмотрите ниже, чтобы увидеть важные соответствующие фрагменты для фотосъемки.

import React from 'react'
/* ... other imports
*/

export default CameraScene = () => {
  /* ... other state and permission logic
  */
  const ref = useRef(null)
  const _takePhoto = async () => {
    const photo = await ref.current.takePictureAsync()
    console.debug(photo)
  }
  return (
    <Camera style = {{flex: 1}} ref = {ref}> /* ...
    ... other ui logic
    */
    </Camera>
  ) 
}

Подробнее про useRef здесь https://reactjs.org/docs/hooks-reference.html#useref)

Привет, где мне использовать нижний код?

kd12345 16.03.2021 06:12

Другие вопросы по теме