(转)React Native 使用react-native-image-picker库实现图片上传功能
react-native-image-picker作为一个集成相机和相册的功能的第三方库,因为其使用相对简单受到前端开发人员的喜爱。
react-native-image-picker使用
- 首先,安装下该插件。
npm install react-native-image-picker@latest --save
2. 针对Android和iOS平台分别进行配置
## android 平台配置
1. 在android/settings.gradle文件中添加如下代码:
include ':react-native-image-picker'
project(':react-native-image-picker').projectDir = new File(settingsDir, '../node_modules/react-native-image-picker/android')
2. 在android/app/build.gradle文件的dependencies中添加如下代码:
compile project(':react-native-image-picker')
3. 在AndroidManifest.xml文件中添加权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4. 最后在MainApplication.Java文件中添加如下代码:
import com.imagepicker.ImagePickerPackage;
new ImagePickerPackage()
## iOS 平台配置
1,打开Xcode打开项目,点击根目录,右键选择 Add Files to ‘XXX’,选中项目中的该路径下的文件即可:node_modules -> react-native-image-picker -> ios -> select RNImagePicker.xcodeproj
2,添加成功后使用link命令:react-native link react-native-image-picker 。
3,打开项目依次使用Build Phases -> Link Binary With Libraries将RNImagePicker.a添加到项目依赖。
4,对于iOS 10+设备,需要在info.plist中配置NSPhotoLibraryUsageDescription和NSCameraUsageDescription。
react-native-image-picker示例
为了项目使用的方便,我们将其封装为一个组件CameraButton.js。代码如下:
import React from 'react'
import {
TouchableOpacity,
StyleSheet,
Platform,
ActivityIndicator,
View,
Text,
ToastAndroid
} from 'react-native' var ImagePicker = require('react-native-image-picker');
import Icon from 'react-native-vector-icons/Ionicons'; const options = {
title: '选择图片',
cancelButtonTitle: '取消',
takePhotoButtonTitle: '拍照',
chooseFromLibraryButtonTitle: '图片库',
cameraType: 'back',
mediaType: 'photo',
videoQuality: 'high',
durationLimit: 10,
maxWidth: 600,
maxHeight: 600,
aspectX: 2,
aspectY: 1,
quality: 0.8,
angle: 0,
allowsEditing: false,
noData: false,
storageOptions: {
skipBackup: true,
path: 'images'
}
}; class CameraButton extends React.Component {
constructor(props){
super(props);
this.state = {
loading:false
}
}
render() {
const {photos,type} = this.props;
let conText;
if(photos.length > 0){
conText = (<View style={styles.countBox}>
<Text style={styles.count}>{photos.length}</Text>
</View>);
}
return (
<TouchableOpacity
onPress={this.showImagePicker.bind(this)}
style={[this.props.style,styles.cameraBtn]}>
<View>
<Icon name="md-camera" color="#aaa" size={34}/>
{conText}
</View>
</TouchableOpacity>
)
} showImagePicker() {
ImagePicker.showImagePicker(options, (response) => {
if (response.didCancel) {
console.log('User cancelled image picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else { let source; if (Platform.OS === 'android') {
source = {uri: response.uri, isStatic: true}
} else {
source = {uri: response.uri.replace('file://', ''), isStatic: true}
} let file;
if(Platform.OS === 'android'){
file = response.uri
}else {
file = response.uri.replace('file://', '')
} this.setState({
loading:true
});
this.props.onFileUpload(file,response.fileName||'未命名文件.jpg')
.then(result=>{
this.setState({
loading:false
})
})
}
});
}
}
const styles = StyleSheet.create({
cameraBtn: {
padding:5
},
count:{
color:'#fff',
fontSize:12
},
fullBtn:{
justifyContent:'center',
alignItems:'center',
backgroundColor:'#fff'
},
countBox:{
position:'absolute',
right:-5,
top:-5,
alignItems:'center',
backgroundColor:'#34A853',
width:16,
height:16,
borderRadius:8,
justifyContent:'center'
}
}); export default CameraButton;
然后在需要使用的地方引入。
import CameraButton from '../../component/huar/cameraButton' <CameraButton style={styles.cameraBtn}
photos={[]}
onFileUpload={this.onFileUpload} />
点击上传事件:
onFileUpload(file, fileName){
return this.props.uploadAvatar({
id: this.props.user.ID,
type:'logo',
obj:'user',
corpId: this.props.cropId
}, file, fileName)}
Action请求代码:
function actions(dispatch) {
return {
fileUrl,fileName)=>dispatch(Actions.uploadAvatar(params, fileUrl,fileName))
}
}
actions中的uploadAvatar函数如下。
function uploadAvatar(params, fileUrl, fileName) {
return dispatch=> {
return UserService.uploadImage(params, fileUrl, fileName)
.then(result=> {
dispatch({
type: UPDATE_AVATAR,
path: result.path
})
return result
})
}
} //UserService.uploadImage代码如下
export function uploadImage(params, fileUrl,fileName) {
return http.uploadFile(`${config.UploadImage}`, params, fileUrl,fileName)
}
UserService函数的http异步上传图片代码如下:
let queryString = require('query-string');
import Storage from './storage'
import {
Platform
} from 'react-native' const os = Platform.OS; async function uploadFile(url, params, fileUrl,fileName) {
let Access_Token = await Storage.getItem('Access_Token');
let data = new FormData(); data.append('file', {
uri: fileUrl,
name: fileName,
type: 'image/jpeg'
}); Object.keys(params).forEach((key)=> {
if (params[key] instanceof Date) {
data.append(key, value.toISOString())
} else {
data.append(key, String(params[key]))
}
}); const fetchOptions = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Access_Token': Access_Token ? Access_Token : '',
'UserAgent':os
},
body: data
}; return fetch(url, fetchOptions)
.then(checkStatus)
.then(parseJSON)
}
封装上传
let common_url = 'http://192.168.1.1:8080/'; //服务器地址
let token = ''; //用户登陆后返回的token function uploadImage(url,params){
return new Promise(function (resolve, reject) {
let formData = new FormData();
for (var key in params){
formData.append(key, params[key]);
}
let file = {uri: params.path, type: 'application/octet-stream', name: 'image.jpg'};
formData.append("file", file);
fetch(common_url + url, {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data;charset=utf-8',
"x-access-token": token,
},
body: formData,
}).then((response) => response.json())
.then((responseData)=> {
console.log('uploadImage', responseData);
resolve(responseData);
})
.catch((err)=> {
console.log('err', err);
reject(err);
});
});
}
let params = {
userId:'abc12345', //用户id
path:'file:///storage/emulated/0/Pictures/image.jpg' //本地文件地址
}
uploadImage('app/uploadFile',params )
.then( res=>{
//请求成功
if(res.header.statusCode == 'success'){
//这里设定服务器返回的header中statusCode为success时数据返回成功
upLoadImgUrl = res.body.imgurl; //服务器返回的地址
}else{
//服务器返回异常,设定服务器返回的异常信息保存在 header.msgArray[0].desc
console.log(res.header.msgArray[0].desc);
}
}).catch( err=>{
//请求失败
})
附:http://lib.csdn.net/article/reactnative/58022?knId=1415
使用fetch+formData实现图片上传
(转)React Native 使用react-native-image-picker库实现图片上传功能的更多相关文章
- 基于Node的React图片上传组件实现
写在前面 红旗不倒,誓把JavaScript进行到底!今天介绍我的开源项目 Royal 里的图片上传组件的前后端实现原理(React + Node),花了一些时间,希望对你有所帮助. 前端实现 遵循R ...
- 分享一个react 图片上传组件 支持OSS 七牛云
react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 排序等功能 需要 react 版本大于 v ...
- React后台管理手动封装图片上传组件
分为两个文件夹,index.js(逻辑文件) styled.js(样式文件) index.js文件,编写完成之后在对应的地方引入即可 import React from "react&quo ...
- React+wangeditor+node富文本处理带图片上传
最近有个需求出现在我的视野中,因为我的另外的博客需要上传文章,但是我不想每次都在我的数据库中慢慢的修改格式,所以我另做了一个后台去编辑文本后发送给服务器,那么这里就涉及到两点,一个是富文本,一个是需要 ...
- React+Antd+Antd-Img-Crop实现上传固定大小的裁剪头像或者图片(且可控制图片数量)
见章知著 1024,程序员们节日快乐!本文主要讲述react配合antd以及react-img-crop第三方库实现一个可控的图片上传功能. 运行项目 需要具有node环境 第三方库安装 1.antd ...
- react native中如何往服务器上传网络图片
let common_url = 'http://192.168.1.1:8080/'; //服务器地址 let token = ''; //用户登陆后返回的token /** * 使用fetch实现 ...
- node.js+react全栈实践-Form中按照指定路径上传文件并
书接上回,讲到“使用同一个新增弹框”中有未解决的问题,比如复杂的字段,文件,图片上传,这一篇就解决文件上传的问题.这里的场景是在新增弹出框中要上传一个图片,并且这个上传组件放在一个Form中,和其他文 ...
- 封装react antd的upload上传组件
上传文件也是我们在实际开发中常遇到的功能,比如上传产品图片以供更好地宣传我们的产品,上传excel文档以便于更好地展示更多的产品信息,上传zip文件以便于更好地收集一些资料信息等等.至于为何要把上传组 ...
- React项目中使用wangeditor以及扩展上传附件菜单
在最近的工作中需要用到富文本编辑器,结合项目的UI样式以及业务需求,选择了wangEditor.另外在使用的过程中发现wangEditor只有上传图片和视频的功能,没有上传文本附件的功能,所以需要对其 ...
随机推荐
- BZOJ 1294 [SCOI2009]围豆豆Bean ——计算几何
显然我们不可能表示出一台路径,因为实在是太复杂了. 所以我们可以记录一下路径对答案的影响,显然路径对答案影响相同的时候,答案更优,所以我们可以用影响来代替路径. 所以我们考虑状压一下所有的豆子有没有被 ...
- 【2018.10.15】WZJ笔记(数论)
1. 证明:对于任意质数$p\gt 3$,$p^2-1$能被$24$整除. 证:平方差公式,$p^2-1 = (p-1)(p+1)$. 再把$24$分解质因数$2^3*3$. 三个相邻的自然数中至少有 ...
- 【bzoj4004】【JLOI2015】装备购买 (线性基+高斯消元)
Description 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 < ...
- Chapter 4-5
1.切片对象 sequence[起始索引:结束索引:步进值] 对象身份的比较 is /is not 2.eval()参数是一个字符串, 可以把这个字符串当成表达式来求值. >>>x ...
- 1109 NOIP 模拟考试
NOIP2016 模拟赛 ——那些年,我们学过的文化课 背单词(word.c/cpp/pas)[题目描述]fqk 退役后开始补习文化课啦, 于是他打开了英语必修一开始背单词. 看着满篇的单词非常头疼, ...
- windows创建任务计划(周期执行bat脚本)
https://jingyan.baidu.com/article/ca00d56c767cfae99febcf73.html windows找到任务计划程序: 这台电脑->管理
- Codeforces Round #267 (Div. 2) C. George and Job (dp)
wa哭了,,t哭了,,还是看了题解... 8170436 2014-10-11 06:41:51 njczy2010 C - George and Jo ...
- spring boot -- 无法读取html文件,碰到的坑
碰到的坑,无法Controller读取html文件 1. Controller类一定要使用@Controller注解,不要用@RestController 2. resource目录下创建templa ...
- JS实现限行
一.JS代码实现 1. 机动车辆限行如下图所示: 具体详情请访问:http://www.bjjtgl.gov.cn/zhuanti/10weihao/index.html 2.JS代码实现 <! ...
- 2019年春招Android方向腾讯电话面试
第一问:TCP与UDP的区别 参考答案: 1.基于连接与无连接 2.TCP要求系统资源较多,UDP较少: 3.UDP程序结构较简单 4.流模式(TCP)与数据报模式(UDP); 5.TCP保证数据正确 ...