React Native expo项目使用expo-image-picker上传图片
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."
}
]
]
}
}
我的RN代码:
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' } }),
官方RN代码:
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接收文件上传:
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库。
expo install expo-image-picker
然后,您可以使用以下代码来选择图片并上传:
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
函数将该数据发送到后端。
以下是一个使用绝对路径上传图片的示例代码:
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-Type
为multipart/form-data
,以便服务器正确解析请求。
希望这可以帮助到您!如果您有任何其他问题,请随时提问。