You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native单屏集成相机与照片上传功能实现方案咨询

在React Native中实现同屏拍照+相册选择的方案

你可以通过以下几种方案实现类似原生相机应用的同屏拍照/相册选择体验,无需切换页面:

方案1:自定义操作栏 + 现有图片选择库

基于你熟悉的react-native-image-picker或react-native-image-crop-picker,在当前页面底部添加操作按钮,点击触发对应功能即可,完全不需要切换页面。

示例代码(基于react-native-image-picker):

import React, { useState } from 'react';
import { View, Button, Image, StyleSheet } from 'react-native';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';

const PhotoPickerScreen = () => {
  const [selectedImage, setSelectedImage] = useState(null);

  // 拍照逻辑
  const handleTakePhoto = () => {
    const options = {
      mediaType: 'photo',
      quality: 0.8,
      maxWidth: 1000,
      maxHeight: 1000,
    };
    launchCamera(options, (response) => {
      if (response.didCancel) return;
      if (response.assets?.[0]) {
        setSelectedImage(response.assets[0].uri);
        // 直接调用上传逻辑
        uploadImage(response.assets[0].uri);
      }
    });
  };

  // 相册选择逻辑
  const handlePickFromGallery = () => {
    const options = {
      mediaType: 'photo',
      selectionLimit: 1,
    };
    launchImageLibrary(options, (response) => {
      if (response.didCancel) return;
      if (response.assets?.[0]) {
        setSelectedImage(response.assets[0].uri);
        uploadImage(response.assets[0].uri);
      }
    });
  };

  const uploadImage = (uri) => {
    // 实现你的上传逻辑,比如用fetch或axios
    console.log('开始上传图片:', uri);
  };

  return (
    <View style={styles.container}>
      {/* 图片预览区域 */}
      {selectedImage && (
        <Image source={{ uri: selectedImage }} style={styles.previewImage} />
      )}
      {/* 底部操作按钮栏 */}
      <View style={styles.buttonContainer}>
        <Button title="拍照" onPress={handleTakePhoto} />
        <Button title="从相册选择" onPress={handlePickFromGallery} />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  previewImage: {
    width: 300,
    height: 300,
    marginBottom: 20,
    borderRadius: 10,
  },
  buttonContainer: {
    flexDirection: 'row',
    gap: 20,
  },
});

export default PhotoPickerScreen;

方案2:嵌入相机预览到当前页面(更贴近原生体验)

如果需要像原生相机那样直接在当前屏幕显示相机预览,同时提供相册入口,可以使用react-native-vision-camera(新一代相机库)嵌入相机组件,再搭配相册选择功能。

示例代码(基于react-native-vision-camera):

import React, { useState, useRef } from 'react';
import { View, Button, Image, StyleSheet } from 'react-native';
import { Camera, useCameraDevices, takePicture } from 'react-native-vision-camera';
import { launchImageLibrary } from 'react-native-image-picker';

const CameraScreen = () => {
  const [hasPermission, setHasPermission] = useState(false);
  const [capturedImage, setCapturedImage] = useState(null);
  const cameraRef = useRef(null);
  const devices = useCameraDevices();
  const device = devices.back;

  React.useEffect(() => {
    (async () => {
      const status = await Camera.requestCameraPermission();
      setHasPermission(status === 'authorized');
    })();
  }, []);

  // 拍照操作
  const handleCapture = async () => {
    if (cameraRef.current == null) return;
    const photo = await takePicture(cameraRef.current, {
      quality: 0.8,
    });
    setCapturedImage(photo.path);
    uploadImage(photo.path);
  };

  // 相册选择操作
  const handlePickFromGallery = () => {
    launchImageLibrary({ mediaType: 'photo', selectionLimit: 1 }, (response) => {
      if (response.assets?.[0]) {
        setCapturedImage(response.assets[0].uri);
        uploadImage(response.assets[0].uri);
      }
    });
  };

  const uploadImage = (uri) => {
    // 上传逻辑
    console.log('上传图片:', uri);
  };

  if (device == null || !hasPermission) return <View />;

  return (
    <View style={styles.container}>
      {/* 相机预览区域 */}
      {!capturedImage && (
        <Camera
          ref={cameraRef}
          style={styles.camera}
          device={device}
          isActive={true}
        />
      )}
      {/* 已拍摄图片预览 */}
      {capturedImage && (
        <Image source={{ uri: capturedImage }} style={styles.previewImage} />
      )}
      {/* 底部操作按钮 */}
      <View style={styles.buttonContainer}>
        <Button title={capturedImage ? '重新拍摄' : '拍照'} onPress={handleCapture} />
        <Button title="从相册选择" onPress={handlePickFromGallery} />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  camera: {
    flex: 1,
  },
  previewImage: {
    flex: 1,
    width: '100%',
  },
  buttonContainer: {
    position: 'absolute',
    bottom: 20,
    width: '100%',
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
});

export default CameraScreen;

必做配置:权限申请

  • iOS:在Info.plist中添加NSCameraUsageDescription和NSPhotoLibraryUsageDescription字段,填写权限申请说明。
  • Android:在AndroidManifest.xml中添加<uses-permission android:name="android.permission.CAMERA" />,Android 13+还需添加<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />。

内容的提问来源于stack exchange,提问作者coder03

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:01:17