【问题标题】:How to take a picture and get the data in React Native with the mobile cameraReact Native 中如何使用手机摄像头拍照并获取数据
【发布时间】:2018-08-25 18:24:19
【问题描述】:

在你说这是重复之前,让我解释一下。 我知道如何在 React Native 中使用 Camera,但是上个月在 Android(Java) 中我以一种简单的方式管理设备摄像头,我什至不必创建一个新的 View 来使用它。我只是做了这样的事情:

Uri mOutputFileUri;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mOutputFileUri); // URI of the file where pic will be stored

startActivityForResult(intent, TAKE_PICTURE_FROM_CAMERA);

基本上这会自动打开相机,当按下“拍照按钮”时,会调用 onActivityForResult() 方法,获取要管理的图像数据。

所以,我的疑问是,有没有办法在 React Native 中做到这一点?我的意思是,调用一个自动打开相机并返回数据的方法?

非常感谢。

【问题讨论】:

    标签: javascript android react-native mobile camera


    【解决方案1】:

    最简单的方法是使用 ImagePicker 库https://github.com/react-community/react-native-image-picker

    这允许您打开本机相机并使用照片中的数据获取提供的回调。

    ImagePicker.launchCamera(options, (response)  => {
        // Response data
    });
    

    【讨论】:

      【解决方案2】:

      您还可以使用 expo-camera 和 expo-av(用于视频)。这是一个快速原型,它还管理设备权限。

      import React, { useState, useRef, useEffect } from "react";
      import {
        StyleSheet,
        Dimensions,
        View,
        Text,
        TouchableOpacity,
        SafeAreaView,
      } from "react-native";
      import { Camera } from "expo-camera";
      import { Video } from "expo-av";
      const WINDOW_HEIGHT = Dimensions.get("window").height;
      const closeButtonSize = Math.floor(WINDOW_HEIGHT * 0.032);
      const captureSize = Math.floor(WINDOW_HEIGHT * 0.09);
      export default function App() {
        const [hasPermission, setHasPermission] = useState(null);
        const [cameraType, setCameraType] = useState(Camera.Constants.Type.back);
        const [isPreview, setIsPreview] = useState(false);
        const [isCameraReady, setIsCameraReady] = useState(false);
        const [isVideoRecording, setIsVideoRecording] = useState(false);
        const [videoSource, setVideoSource] = useState(null);
        const cameraRef = useRef();
        useEffect(() => {
          (async () => {
            const { status } = await Camera.requestPermissionsAsync();
            setHasPermission(status === "granted");
          })();
        }, []);
        const onCameraReady = () => {
          setIsCameraReady(true);
        };
        const takePicture = async () => {
          if (cameraRef.current) {
            const options = { quality: 0.5, base64: true, skipProcessing: true };
            const data = await cameraRef.current.takePictureAsync(options);
            const source = data.uri;
            if (source) {
              await cameraRef.current.pausePreview();
              setIsPreview(true);
              console.log("picture source", source);
            }
          }
        };
        const recordVideo = async () => {
          if (cameraRef.current) {
            try {
              const videoRecordPromise = cameraRef.current.recordAsync();
              if (videoRecordPromise) {
                setIsVideoRecording(true);
                const data = await videoRecordPromise;
                const source = data.uri;
                if (source) {
                  setIsPreview(true);
                  console.log("video source", source);
                  setVideoSource(source);
                }
              }
            } catch (error) {
              console.warn(error);
            }
          }
        };
        const stopVideoRecording = () => {
          if (cameraRef.current) {
            setIsPreview(false);
            setIsVideoRecording(false);
            cameraRef.current.stopRecording();
          }
        };
        const switchCamera = () => {
          if (isPreview) {
            return;
          }
          setCameraType((prevCameraType) =>
            prevCameraType === Camera.Constants.Type.back
              ? Camera.Constants.Type.front
              : Camera.Constants.Type.back
          );
        };
        const cancelPreview = async () => {
          await cameraRef.current.resumePreview();
          setIsPreview(false);
          setVideoSource(null);
        };
        const renderCancelPreviewButton = () => (
          <TouchableOpacity onPress={cancelPreview} style={styles.closeButton}>
            <View style={[styles.closeCross, { transform: [{ rotate: "45deg" }] }]} />
            <View
              style={[styles.closeCross, { transform: [{ rotate: "-45deg" }] }]}
            />
          </TouchableOpacity>
        );
        const renderVideoPlayer = () => (
          <Video
            source={{ uri: videoSource }}
            shouldPlay={true}
            style={styles.media}
          />
        );
        const renderVideoRecordIndicator = () => (
          <View style={styles.recordIndicatorContainer}>
            <View style={styles.recordDot} />
            <Text style={styles.recordTitle}>{"Recording..."}</Text>
          </View>
        );
        const renderCaptureControl = () => (
          <View style={styles.control}>
            <TouchableOpacity disabled={!isCameraReady} onPress={switchCamera}>
              <Text style={styles.text}>{"Flip"}</Text>
            </TouchableOpacity>
            <TouchableOpacity
              activeOpacity={0.7}
              disabled={!isCameraReady}
              onLongPress={recordVideo}
              onPressOut={stopVideoRecording}
              onPress={takePicture}
              style={styles.capture}
            />
          </View>
        );
        if (hasPermission === null) {
          return <View />;
        }
        if (hasPermission === false) {
          return <Text style={styles.text}>No access to camera</Text>;
        }
        return (
          <SafeAreaView style={styles.container}>
            <Camera
              ref={cameraRef}
              style={styles.container}
              type={cameraType}
              flashMode={Camera.Constants.FlashMode.on}
              onCameraReady={onCameraReady}
              onMountError={(error) => {
                console.log("cammera error", error);
              }}
            />
            <View style={styles.container}>
              {isVideoRecording && renderVideoRecordIndicator()}
              {videoSource && renderVideoPlayer()}
              {isPreview && renderCancelPreviewButton()}
              {!videoSource && !isPreview && renderCaptureControl()}
            </View>
          </SafeAreaView>
        );
      }
      const styles = StyleSheet.create({
        container: {
          ...StyleSheet.absoluteFillObject,
        },
        closeButton: {
          position: "absolute",
          top: 35,
          left: 15,
          height: closeButtonSize,
          width: closeButtonSize,
          borderRadius: Math.floor(closeButtonSize / 2),
          justifyContent: "center",
          alignItems: "center",
          backgroundColor: "#c4c5c4",
          opacity: 0.7,
          zIndex: 2,
        },
        media: {
          ...StyleSheet.absoluteFillObject,
        },
        closeCross: {
          width: "68%",
          height: 1,
          backgroundColor: "black",
        },
        control: {
          position: "absolute",
          flexDirection: "row",
          bottom: 38,
          width: "100%",
          alignItems: "center",
          justifyContent: "center",
        },
        capture: {
          backgroundColor: "#f5f6f5",
          borderRadius: 5,
          height: captureSize,
          width: captureSize,
          borderRadius: Math.floor(captureSize / 2),
          marginHorizontal: 31,
        },
        recordIndicatorContainer: {
          flexDirection: "row",
          position: "absolute",
          top: 25,
          alignSelf: "center",
          justifyContent: "center",
          alignItems: "center",
          backgroundColor: "transparent",
          opacity: 0.7,
        },
        recordTitle: {
          fontSize: 14,
          color: "#ffffff",
          textAlign: "center",
        },
        recordDot: {
          borderRadius: 3,
          height: 6,
          width: 6,
          backgroundColor: "#ff0000",
          marginHorizontal: 5,
        },
        text: {
          color: "#fff",
        },
      });
      
      

      来源 - Instamobile

      【讨论】:

        猜你喜欢
        • 2021-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多