react native(expo)选择图片/视频并上传阿里云oss

1.引入相关库:

复制代码
@ant-design/react-native ant风格UI库
expo-file-system 文件访问
expo-image-picker 图片/视频选择器

2.新建图片选择并上传的帮助类

复制代码
import { Toast } from '@ant-design/react-native';
import * as FileSystem from "expo-file-system";
import * as ImagePicker from 'expo-image-picker';
import AppService from "../api/app";
import Loading from "../components/ui/Loading";
import LogUtil from "./log_util";

// 从后端api获取
export let ossUrl = 'https://oss-2008.oss-cn-hongkong.aliyuncs.com';
let ossConfig = null;

/**
 * @desc 选择相册图片
 */
export const pickImage = async (mediaTypes = ImagePicker.MediaTypeOptions.Images) => {
    // No permissions request is necessary for launching the image library
    let result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: mediaTypes,
        allowsEditing: true,
        aspect: null,
        quality: 0.5,
    });

    LogUtil.log('pick image result = ', result);

    if (result.canceled) {
        return null;
    }
    if (mediaTypes === ImagePicker.MediaTypeOptions.Images) {
        if (result.assets[0]?.fileSize/(1024*1024) > 2) {
            Toast.fail('图片不能超过2MB');
            return null;
        }
    } else if (mediaTypes === ImagePicker.MediaTypeOptions.Videos) {
        if (result.assets[0]?.fileSize/(1024*1024) > 10) {
            Toast.fail('视频不能超过10MB');
            return null;
        }
    } else {}

    return result.assets[0].uri;
};

export const uploadImage = async (fileName, filePath, nav) => {
    Loading.show();
    // 从后端获取阿里云oss相关凭证
    const res = await AppService.getAliyunOssToken({}, nav);
    if (res.code === 200) {
        /*
        *
        * host = obj['host']
            policyBase64 = obj['policy']
            accessid = obj['accessid']
            signature = obj['signature']
            expire = parseInt(obj['expire'])
            callbackbody = obj['callback']
            key = obj['dir']
        *
        *  */
        ossConfig = res.data;
        ossUrl = ossConfig['host'];
    } else {
        Loading.hide();
        Toast.info('获取oss token信息失败')
        return null;
    }

    if (filePath && filePath.length > 0) {
        const split = filePath.split('.');
        let realFileName = (!fileName || fileName.length === 0) ? `${random_string()}.${split[split.length - 1]}` : `${fileName}.${split[split.length - 1]}`;
        let key = `${ossConfig['dir']}${realFileName}`;
        let imageServicePath = `${ossConfig['host']}/${key}`;

        try {
            LogUtil.log('ossUrl = ', ossUrl)
            // 使用FileSystem.uploadAsync上传文件至阿里云oss
            const response = await FileSystem.uploadAsync(`${ossUrl}`, filePath, {
                fieldName: 'file',
                httpMethod: 'POST',
                uploadType: FileSystem.FileSystemUploadType.MULTIPART,
                parameters: {
                    'name': realFileName,
                    'key': key,
                    'policy': ossConfig['policy'],
                    'OSSAccessKeyId': ossConfig['accessid'],
                    'success_action_status': '200',
                    'callback': ossConfig['callback'],
                    'signature': ossConfig['signature']
                }
            })

            LogUtil.log('response', JSON.stringify(response), 'imageServicePath', imageServicePath)
            Loading.hide();
            if (response.status !== 200) {
                return null;
            }
            return { imageServicePath, fileName: key };
        } catch (error) {
            LogUtil.error(error)
        }
    }
    Loading.hide();
    return null;
}

const random_string = (len) => {
    len = len || 32;
    let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    let maxPos = chars.length;
    let pwd = '';
    for (let i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
}

3.代码中调用:

3.1 只选择图片、视频后用于展示

复制代码
pickImage(mediaTypes).then(uri => {
            if (uri) {
                // uri可直接使用ImageView组件展示
            }
        })

3.2 选择图片、视频再上传阿里云oss后展示

复制代码
    const ChatTypes = {
        voice: 6,
        image: 2,
        video: 3,
        text: 1,
        systemTips: 4,
        autoText: 5,
    }    
    
    let imageSendValue = '';
    let videoSendValue = '';
    let imageUri = '';
    let videoUri = '';
    const pickAndUploadImage = (type) => {
        let mediaTypes = type === ChatTypes.image ? ImagePicker.MediaTypeOptions.Images : ImagePicker.MediaTypeOptions.Videos;
        pickImage(mediaTypes).then(uri => {
            if (uri) {
                uploadImage(null, uri, navigation).then(res => {
                    if (!res) {
                        Toast.info(i18n.t("Chat.UploadFail"));
                        return;
                    }
                    LogUtil.log('imageServicePath = ', res?.imageServicePath, 'fileName = ', res?.fileName)

                    switch (type) {
                        case ChatTypes.image:
                            imageSendValue = res?.fileName;
                            imageUri = uri;
                            // sendMessage(ChatTypes.image, imageSendValue, imageUri);
                            break;
                        case ChatTypes.video:
                            videoSendValue = res?.fileName;
                            videoUri = uri;
                            // sendMessage(ChatTypes.video, videoSendValue, videoUri);
                            break;
                        default:
                            break;
                    }
                })
            }
        })
    }
相关推荐
killerbasd4 小时前
还是迷茫 5.3
前端·react.js·前端框架
LemonSmile_6 小时前
CC Switch 配置 Claude Code 接入 阿里云百炼
阿里云·云计算·claude·百炼
江南十四行10 小时前
ReAct Agent 基本理论与项目实战(一)
前端·react.js·前端框架
谢尔登13 小时前
10_从 React Hooks 本质看 useState
前端·ubuntu·react.js
辰同学ovo13 小时前
从全局登录状态管理学习 Redux
前端·javascript·学习·react.js
光影少年14 小时前
reeact虚拟DOM、Diff算法原理、key的作用与为什么不能用index
前端·react.js·掘金·金石计划
江南十四行15 小时前
ReAct Agent 基本理论与项目实战(二)
前端·react.js·前端框架
摘星编程16 小时前
当AI开始学会“使用工具“——从ReAct到MCP,大模型如何获得真正的行动力
前端·人工智能·react.js
xiejava101817 小时前
个人博客Hugo接入阿里云腾讯云ESA边缘加速实战指南
阿里云·云计算·腾讯云·hugo
啊哈一半醒18 小时前
React 核心知识点系统总结:从基础语法到高级 API,一篇文章梳理完整学习路线
javascript·学习·react.js