在React Native中,图像拾取器允许用户从图像拾取器访问相机

c6ubokkw  于 2023-06-06  发布在  React
关注(0)|答案(1)|浏览(225)

我正在使用Expo在React Native中编写应用程序。我使用expo-image-picker来允许用户上传图片。我看到有一个供用户从照片库中选择图像的选项(launchImageLibraryAsync)和一个供用户使用相机拍照的选项(launchCameraAsync)。然而,对于大多数应用程序,如果您打开了照片库对话框,通常会有一个图标切换到相机,反之亦然,如果您在相机中,通常会有一个图标切换到照片库。这似乎不是expo-image-picker的情况,如果我在相机中,没有直接进入照片库的选项,如果你在相机中,没有直接进入照片库的选项。我真的不希望我的应用程序上有两个单独的按钮来打开画廊和相机。有没有办法使用expo-image-picker在照片库和相机之间切换?

cbjzeqam

cbjzeqam1#

我让我的图像输入组件有一个模式,“照片”,“相机”,或“两者兼而有之”(默认值)。
当您按下输入时,如果它是“两者”,它会带出一个带有相机/照片/取消按钮的警报,并启动相应的界面。
下面是我的代码:

import React, {useEffect} from 'react';
import {Alert, Image, StyleSheet, TouchableWithoutFeedback, View} from "react-native";

import colors from '../config/colors'
import Icon from './Icon';
import useCamera from '../hooks/useCamera';
import usePhotos from '../hooks/usePhotos';

function ImageInput({imageUri, onChangeImage, onCancel = ()  => {}, mode = 'both'}) {

    const camera = useCamera();
    const photos = usePhotos();

    const handlePress = async () => {
        if (!imageUri) {
            switch (mode) {
                case 'camera':
                    selectImage('camera')
                    break;
                case 'photos':
                    selectImage('photos');
                    break;
                case 'both':
                default:
                    Alert.alert(
                        'Please choose',
                        null,
                        [
                            { text: 'Photos', onPress: () => selectImage('photos') },
                            { text: 'Camera', onPress: () => selectImage('camera') },
                            { text: 'Cancel', style: 'cancel' }
                        ]
                    );
            }

        } else {
            Alert.alert('Remove', 'are you sure you want to remove this image?', [
                { text: 'Yes', onPress: () => onChangeImage(null)},
                { text: 'No'},
            ]);
        }
    };

    const selectImage = async (pickerType) => {
        try {
            if (pickerType === 'camera') {
                const result = await camera.takePhoto({
                    allowsEditing: true,
                    quality: 0.5
                })
                result.canceled ? onCancel() : onChangeImage(result.assets[0].uri);

            } else {
                const result = await photos.selectImage({
                    quality: 0.5
                });
                result.canceled ? onCancel() : onChangeImage(result.assets[0].uri);
            }

        } catch (error) {
            Alert.alert('Image error', 'Error reading image');
            console.log(error);
        }
    };

    return (
        <TouchableWithoutFeedback onPress={handlePress}>
            <View style={styles.container}>
                {!imageUri ? (
                    <Icon name="camera" size={75} iconColor={colors.medium} />
                ) : (
                    <Image source={{ uri: imageUri }} style={styles.image} />
                )}
            </View>
        </TouchableWithoutFeedback>
    );
}

const styles = StyleSheet.create({
    container: {
        alignItems: 'center',
        backgroundColor: colors.light,
        borderRadius: 15,
        justifyContent: 'center',
        height: 100,
        width: 100,
        overflow: 'hidden'
    },
    image: {
        width: '100%',
        height: '100%',
    }
})

export default ImageInput;

为了清楚起见,这里是我的useCamera和usePhotos钩子:

import {useEffect} from "react";
import { Camera } from 'expo-camera';
import * as ImagePicker from "expo-image-picker";

export default useCamera = () => {

    const requestPermission = async () => {
        const { granted } = await Camera.requestCameraPermissionsAsync();

        if (!granted) {
            Alert.alert(
                'Device settings alert',
                'You need to allow camera permissions for this to work'
            );
        }
    }

    const takePhoto = async (options) => {
        options = {mediaTypes: ImagePicker.MediaTypeOptions.Images, ...options };

        return await ImagePicker.launchCameraAsync(options);
    }

    useEffect(() => {
        requestPermission();
    }, []);

    return {takePhoto};
};
import {useEffect} from "react";
import * as ImagePicker from "expo-image-picker";

export default usePhotos = () => {

    const requestPermission = async () => {
        const { granted} = await ImagePicker.requestMediaLibraryPermissionsAsync();

        if (!granted) {
            Alert.alert(
                'Device settings alert',
                'You need to allow media library permissions for this to work'
            );
        }
    }

    const selectImage = async (options) => {
        options = {mediaTypes: ImagePicker.MediaTypeOptions.Images, ...options };

        return await ImagePicker.launchImageLibraryAsync(options);
    }

    useEffect(() => {
        requestPermission();
    }, []);

    return {selectImage};
};

相关问题