React Native expo项目使用expo-image-picker上传图片

app.json:

https://docs.expo.dev/versions/latest/sdk/imagepicker/

javascript 复制代码
{
  "expo": {
    "plugins": [
      [
        "expo-image-picker",
        {
          "photosPermission": "The app accesses your photos to let you share them with your friends."
        }
      ]
    ]
  }
}

我的RN代码:

javascript 复制代码
import * as ImagePicker from 'expo-image-picker'


  const handleUploadAvatar = async () => {
    try {
      let result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.All,
        base64: true,
        //allowsEditing: true,
        //aspect: [4, 3],
        //quality: 1,
      })
      if (!result.canceled) {
        const formData = new FormData()
        let uri = result.assets[0].uri
        let uriArr = uri.split('/')
        let name = uriArr[uriArr.length - 1]
        console.log(uri)
        setAvatar(uri)
        formData.append('file', {
          uri,
          name,
          //type: result.assets[0].type,
          type: 'image/jpeg',
        })
        Api.h5.uploadFile(formData).then((res) => {
          console.log(res)
          if (res.code === 200) {
            console.log('成功')
          }
        })
      } else {
        console.log('取消文件选择')
      }
    } catch (error) {
      console.log('选择文件时出错', error)
    }
  }




        <View style={style.mRegisterRow}>
          <View style={style.mRegisterAvavtarTextWrap}>
            <Text style={style.mRegisterAvavtarText}>头像</Text>
          </View>
          {avatar ? (
            <TouchableWithoutFeedback onPress={handleUploadAvatar}>
              <Image
                source={{ uri: avatar }}
                style={style.mRegisterAvatar}
              ></Image>
            </TouchableWithoutFeedback>
          ) : (
            <View style={style.mRegisterUploadIcoWrap}>
              <Icon
                name={'add'}
                onPress={handleUploadAvatar}
                style={style.mRegisterUploadIcon}
              ></Icon>
            </View>
          )}
        </View>
javascript 复制代码
  uploadFile: (data) => common({ url: urls.h5.uploadFile, data, method: 'post', headers: { 'content-type': 'multipart/form-data' } }),

官方RN代码:

javascript 复制代码
import React, { useState, useEffect } from 'react';
import { Button, Image, View, Platform } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

export default function ImagePickerExample() {
  const [image, setImage] = useState(null);

  const pickImage = async () => {
    // No permissions request is necessary for launching the image library
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });

    console.log(result);

    if (!result.canceled) {
      setImage(result.assets[0].uri);
    }
  };

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button title="Pick an image from camera roll" onPress={pickImage} />
      {image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
    </View>
  );
}

后端node接收文件上传:

javascript 复制代码
const multer = require('multer')

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const NODE_ENV = process.env.NODE_ENV || 'development'
    let tempPath = ''
    if (NODE_ENV === 'development') {
      tempPath = '/temp/uploadForDev/upload'
    } else if (NODE_ENV === 'production') {
      tempPath = '/temp/uploadForProd/upload'
    } else if (NODE_ENV === 'codesandbox') {
      tempPath = 'uploadForCodesandbox/upload'
    }
    cb(null, tempPath)
  },
  filename: (req, file, cb) => {
    cb(null, `${Date.now()}-${file.originalname}`)
  },
})

const uploadImgMulter = multer({ storage })

//上传
const uploadFile = (req, res) => {
  res.send({
    code: 200,
    data: { 
      ...req.file, 
      filename: 'upload/' + req.file.filename 
    },
    message: '上传成功',
  })
}



  app.post(urls.light.uploadFile, uploadImgMulter.single('file'),  (req, res) => commonGroup({ req, res, myRoleGroup: roleGroup.notNeeedLogin, callback: uploadFile }) )

chatgpt的回答


expo-image-picker 图片上传

要使用Expo的ImagePicker库进行图片上传,您可以按照以下步骤操作。

首先,确保您已在项目中安装了Expo的ImagePicker库。

bash 复制代码
expo install expo-image-picker

然后,您可以使用以下代码来选择图片并上传:

javascript 复制代码
import React, { useState, useEffect } from 'react';
import { Button, Image, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

const ImagePickerExample = () => {
  const [image, setImage] = useState(null);

  useEffect(() => {
    (async () => {
      // 请求权限
      const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
      if (status !== 'granted') {
        console.log('拒绝访问图片库权限!');
      }
    })();
  }, []);

  const pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });

    console.log(result);

    if (!result.cancelled) {
      // 设置选择的图片
      setImage(result.uri);

      // 上传图片的逻辑
      // ...
    }
  };

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button title="选择图片" onPress={pickImage} />
      {image && <Image source={{ uri: image }} style={{ width: 200, height: 200, marginTop: 20 }} />}
    </View>
  );
};

export default ImagePickerExample;

此示例使用Button和Image组件创建一个简单的界面,点击按钮将触发选择图片的逻辑。选择图片后,将通过设置useState来更新图像状态,并将图像显示在屏幕上。

在pickImage函数中,使用ImagePicker.launchImageLibraryAsync方法来打开本地图库,您可以根据自己的需求配置options参数。选择图片后,将在控制台中打印结果。您可以根据需要将选中的图片上传到服务器。

请注意,在使用ImagePicker之前,您需要在app.json文件中的expo.permissions字段中添加相应的权限(例如:READ_EXTERNAL_STORAGE)。

希望这可以帮助到您!如果您有任何其他问题,请随时提问。

使用图片绝对路径,把图片上传到后端

要使用图片的绝对路径将其上传到后端,您可以使用FormData对象来创建一个包含文件的表单数据,并使用fetch函数将该数据发送到后端。

以下是一个使用绝对路径上传图片的示例代码:

javascript 复制代码
import React, { useState } from 'react';
import { Button, Image, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

const ImagePickerExample = () => {
  const [image, setImage] = useState(null);

  const pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });

    if (!result.cancelled) {
      // 设置选择的图片
      setImage(result.uri);

      // 上传图片到后端
      uploadImage(result.uri);
    }
  };

  const uploadImage = async (uri) => {
    // 创建FormData对象
    const formData = new FormData();
    formData.append('image', { uri, name: 'image.jpg', type: 'image/jpeg' });

    try {
      const response = await fetch('https://your-api-endpoint', {
        method: 'POST',
        body: formData,
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });

      if (response.status === 200) {
        console.log('图片上传成功');
      } else {
        console.log('图片上传失败');
      }
    } catch (error) {
      console.log('上传图片时出错', error);
    }
  };

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button title="选择图片" onPress={pickImage} />
      {image && <Image source={{ uri: image }} style={{ width: 200, height: 200, marginTop: 20 }} />}
    </View>
  );
};

export default ImagePickerExample;

uploadImage函数中,我们创建了一个FormData对象并使用append方法将文件添加到表单数据中。我们指定了文件的名称为image.jpg,文件类型为image/jpeg。然后,我们使用fetch函数将该表单数据发送到后端的API端点。

请将https://your-api-endpoint替换为您实际的后端API的地址。您还可以根据需要配置其他请求参数。

注意:在使用fetch发送请求时,确保设置了正确的请求头Content-Typemultipart/form-data,以便服务器正确解析请求。

希望这可以帮助到您!如果您有任何其他问题,请随时提问。

参考链接:

https://chat.xutongbao.top/

https://docs.expo.dev/versions/latest/sdk/imagepicker/

相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax