React Native expo project uses expo-image-picker to upload images

 app.json:

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

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

 My RN code:

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>
  uploadFile: (data) => common({ url: urls.h5.uploadFile, data, method: 'post', headers: { 'content-type': 'multipart/form-data' } }),

 Official RN code:

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>
  );
}

The backend node receives file uploads:

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's answer

 


 expo-image-picker image upload

To use Expo's ImagePicker library for image uploading, you can follow the steps below.

First, make sure you have installed Expo's ImagePicker library in your project.

expo install expo-image-picker

You can then use the following code to select an image and upload it:

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;

This example uses Button and Image components to create a simple interface, and clicking the button will trigger the logic of selecting an image. After the image is selected, the image state is updated by setting useState and the image is displayed on the screen.

In the pickImage function, use the ImagePicker.launchImageLibraryAsync method to open the local library, and you can configure the options parameter according to your needs. After selecting an image, the result will be printed in the console. You can upload the selected pictures to the server as needed.

Please note that before using ImagePicker, you need to add the corresponding permission (for example: READ_EXTERNAL_STORAGE) in the expo.permissions field in the app.json file.

Hope this helps you! If you have any other questions, please feel free to ask.

Use the absolute path of the image to upload the image to the backend

To upload an image to the backend using its absolute path, you can use FormDataan object to create a form data containing the file and use fetcha function to send that data to the backend.

The following is a sample code for uploading an image using an absolute path:

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;

In uploadImagethe function, we create an FormDataobject and use appendthe method to add the file to the form data. We specified the name of the file as image.jpgand the file type as image/jpeg. We then use fetcha function to send that form data to an API endpoint on the backend.

Please https://your-api-endpointreplace with the address of your actual backend API. You can also configure other request parameters as needed.

Note: When using fetchSend Request, make sure to set the correct request header Content-Typeso multipart/form-datathat the server can correctly parse the request.

Hope this helps you! If you have any other questions, please feel free to ask.

 Reference link:

https://chat.xutongbao.top/

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

Guess you like

Origin blog.csdn.net/xutongbao/article/details/131981469