react-native-image-picker作为一个集成相机和相册的功能的第三方库,因为其使用相对简单受到前端开发人员的喜爱。

react-native-image-picker使用

  1. 首先,安装下该插件。
  1. npm install react-native-image-picker@latest --save

2. 针对Android和iOS平台分别进行配置

## android 平台配置

1. 在android/settings.gradle文件中添加如下代码:

  1. include ':react-native-image-picker'
  2. project(':react-native-image-picker').projectDir = new File(settingsDir, '../node_modules/react-native-image-picker/android')

2. 在android/app/build.gradle文件的dependencies中添加如下代码:

  1. compile project(':react-native-image-picker')

3. 在AndroidManifest.xml文件中添加权限:

  1. <uses-permission android:name="android.permission.CAMERA" />
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

4. 最后在MainApplication.Java文件中添加如下代码:

  1. import com.imagepicker.ImagePickerPackage;
  2. 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。代码如下:

  1. import React from 'react'
  2. import {
  3. TouchableOpacity,
  4. StyleSheet,
  5. Platform,
  6. ActivityIndicator,
  7. View,
  8. Text,
  9. ToastAndroid
  10. } from 'react-native'
  11.  
  12. var ImagePicker = require('react-native-image-picker');
  13. import Icon from 'react-native-vector-icons/Ionicons';
  14.  
  15. const options = {
  16. title: '选择图片',
  17. cancelButtonTitle: '取消',
  18. takePhotoButtonTitle: '拍照',
  19. chooseFromLibraryButtonTitle: '图片库',
  20. cameraType: 'back',
  21. mediaType: 'photo',
  22. videoQuality: 'high',
  23. durationLimit: 10,
  24. maxWidth: 600,
  25. maxHeight: 600,
  26. aspectX: 2,
  27. aspectY: 1,
  28. quality: 0.8,
  29. angle: 0,
  30. allowsEditing: false,
  31. noData: false,
  32. storageOptions: {
  33. skipBackup: true,
  34. path: 'images'
  35. }
  36. };
  37.  
  38. class CameraButton extends React.Component {
  39. constructor(props){
  40. super(props);
  41. this.state = {
  42. loading:false
  43. }
  44. }
  45. render() {
  46. const {photos,type} = this.props;
  47. let conText;
  48. if(photos.length > 0){
  49. conText = (<View style={styles.countBox}>
  50. <Text style={styles.count}>{photos.length}</Text>
  51. </View>);
  52. }
  53. return (
  54. <TouchableOpacity
  55. onPress={this.showImagePicker.bind(this)}
  56. style={[this.props.style,styles.cameraBtn]}>
  57. <View>
  58. <Icon name="md-camera" color="#aaa" size={34}/>
  59. {conText}
  60. </View>
  61. </TouchableOpacity>
  62. )
  63. }
  64.  
  65. showImagePicker() {
  66. ImagePicker.showImagePicker(options, (response) => {
  67. if (response.didCancel) {
  68. console.log('User cancelled image picker');
  69. }
  70. else if (response.error) {
  71. console.log('ImagePicker Error: ', response.error);
  72. }
  73.  
  74. else {
  75.  
  76. let source;
  77.  
  78. if (Platform.OS === 'android') {
  79. source = {uri: response.uri, isStatic: true}
  80. } else {
  81. source = {uri: response.uri.replace('file://', ''), isStatic: true}
  82. }
  83.  
  84. let file;
  85. if(Platform.OS === 'android'){
  86. file = response.uri
  87. }else {
  88. file = response.uri.replace('file://', '')
  89. }
  90.  
  91. this.setState({
  92. loading:true
  93. });
  94. this.props.onFileUpload(file,response.fileName||'未命名文件.jpg')
  95. .then(result=>{
  96. this.setState({
  97. loading:false
  98. })
  99. })
  100. }
  101. });
  102. }
  103. }
  104. const styles = StyleSheet.create({
  105. cameraBtn: {
  106. padding:5
  107. },
  108. count:{
  109. color:'#fff',
  110. fontSize:12
  111. },
  112. fullBtn:{
  113. justifyContent:'center',
  114. alignItems:'center',
  115. backgroundColor:'#fff'
  116. },
  117. countBox:{
  118. position:'absolute',
  119. right:-5,
  120. top:-5,
  121. alignItems:'center',
  122. backgroundColor:'#34A853',
  123. width:16,
  124. height:16,
  125. borderRadius:8,
  126. justifyContent:'center'
  127. }
  128. });
  129.  
  130. export default CameraButton;

然后在需要使用的地方引入。

  1. import CameraButton from '../../component/huar/cameraButton'
  2.  
  3. <CameraButton style={styles.cameraBtn}
  4. photos={[]}
  5. onFileUpload={this.onFileUpload} />
  6. 点击上传事件:
  7. onFileUpload(file, fileName){
  8. return this.props.uploadAvatar({
  9. id: this.props.user.ID,
  10. type:'logo',
  11. obj:'user',
  12. corpId: this.props.cropId
  13. }, file, fileName)}
  14. Action请求代码:
  15. function actions(dispatch) {
  16. return {
  17. fileUrl,fileName)=>dispatch(Actions.uploadAvatar(params, fileUrl,fileName))
  18. }
  19. }

actions中的uploadAvatar函数如下。

  1. function uploadAvatar(params, fileUrl, fileName) {
  2. return dispatch=> {
  3. return UserService.uploadImage(params, fileUrl, fileName)
  4. .then(result=> {
  5. dispatch({
  6. type: UPDATE_AVATAR,
  7. path: result.path
  8. })
  9. return result
  10. })
  11. }
  12. }
  13.  
  14. //UserService.uploadImage代码如下
  15. export function uploadImage(params, fileUrl,fileName) {
  16. return http.uploadFile(`${config.UploadImage}`, params, fileUrl,fileName)
  17. }

UserService函数的http异步上传图片代码如下:

  1. let queryString = require('query-string');
  2. import Storage from './storage'
  3. import {
  4. Platform
  5. } from 'react-native'
  6.  
  7. const os = Platform.OS;
  8.  
  9. async function uploadFile(url, params, fileUrl,fileName) {
  10. let Access_Token = await Storage.getItem('Access_Token');
  11. let data = new FormData();
  12.  
  13. data.append('file', {
  14. uri: fileUrl,
  15. name: fileName,
  16. type: 'image/jpeg'
  17. });
  18.  
  19. Object.keys(params).forEach((key)=> {
  20. if (params[key] instanceof Date) {
  21. data.append(key, value.toISOString())
  22. } else {
  23. data.append(key, String(params[key]))
  24. }
  25. });
  26.  
  27. const fetchOptions = {
  28. method: 'POST',
  29. headers: {
  30. 'Accept': 'application/json',
  31. 'Access_Token': Access_Token ? Access_Token : '',
  32. 'UserAgent':os
  33. },
  34. body: data
  35. };
  36.  
  37. return fetch(url, fetchOptions)
  38. .then(checkStatus)
  39. .then(parseJSON)
  40. }

封装上传

  1. let common_url = 'http://192.168.1.1:8080/'; //服务器地址
  2. let token = ''; //用户登陆后返回的token
  3.  
  4. function uploadImage(url,params){
  5. return new Promise(function (resolve, reject) {
  6. let formData = new FormData();
  7. for (var key in params){
  8. formData.append(key, params[key]);
  9. }
  10. let file = {uri: params.path, type: 'application/octet-stream', name: 'image.jpg'};
  11. formData.append("file", file);
  12. fetch(common_url + url, {
  13. method: 'POST',
  14. headers: {
  15. 'Content-Type': 'multipart/form-data;charset=utf-8',
  16. "x-access-token": token,
  17. },
  18. body: formData,
  19. }).then((response) => response.json())
  20. .then((responseData)=> {
  21. console.log('uploadImage', responseData);
  22. resolve(responseData);
  23. })
  24. .catch((err)=> {
  25. console.log('err', err);
  26. reject(err);
  27. });
  28. });
  29. }
  1. let params = {
  2. userId:'abc12345', //用户id
  3. path:'file:///storage/emulated/0/Pictures/image.jpg' //本地文件地址
  4. }
  5. uploadImage('app/uploadFile',params )
  6. .then( res=>{
  7. //请求成功
  8. if(res.header.statusCode == 'success'){
  9. //这里设定服务器返回的header中statusCode为success时数据返回成功
  10. upLoadImgUrl = res.body.imgurl; //服务器返回的地址
  11. }else{
  12. //服务器返回异常,设定服务器返回的异常信息保存在 header.msgArray[0].desc
  13. console.log(res.header.msgArray[0].desc);
  14. }
  15. }).catch( err=>{
  16. //请求失败
  17. })

附:http://lib.csdn.net/article/reactnative/58022?knId=1415 
使用fetch+formData实现图片上传

(转)React Native 使用react-native-image-picker库实现图片上传功能的更多相关文章

  1. 基于Node的React图片上传组件实现

    写在前面 红旗不倒,誓把JavaScript进行到底!今天介绍我的开源项目 Royal 里的图片上传组件的前后端实现原理(React + Node),花了一些时间,希望对你有所帮助. 前端实现 遵循R ...

  2. 分享一个react 图片上传组件 支持OSS 七牛云

    react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 排序等功能 需要 react 版本大于 v ...

  3. React后台管理手动封装图片上传组件

    分为两个文件夹,index.js(逻辑文件) styled.js(样式文件) index.js文件,编写完成之后在对应的地方引入即可 import React from "react&quo ...

  4. React+wangeditor+node富文本处理带图片上传

    最近有个需求出现在我的视野中,因为我的另外的博客需要上传文章,但是我不想每次都在我的数据库中慢慢的修改格式,所以我另做了一个后台去编辑文本后发送给服务器,那么这里就涉及到两点,一个是富文本,一个是需要 ...

  5. React+Antd+Antd-Img-Crop实现上传固定大小的裁剪头像或者图片(且可控制图片数量)

    见章知著 1024,程序员们节日快乐!本文主要讲述react配合antd以及react-img-crop第三方库实现一个可控的图片上传功能. 运行项目 需要具有node环境 第三方库安装 1.antd ...

  6. react native中如何往服务器上传网络图片

    let common_url = 'http://192.168.1.1:8080/'; //服务器地址 let token = ''; //用户登陆后返回的token /** * 使用fetch实现 ...

  7. node.js+react全栈实践-Form中按照指定路径上传文件并

    书接上回,讲到“使用同一个新增弹框”中有未解决的问题,比如复杂的字段,文件,图片上传,这一篇就解决文件上传的问题.这里的场景是在新增弹出框中要上传一个图片,并且这个上传组件放在一个Form中,和其他文 ...

  8. 封装react antd的upload上传组件

    上传文件也是我们在实际开发中常遇到的功能,比如上传产品图片以供更好地宣传我们的产品,上传excel文档以便于更好地展示更多的产品信息,上传zip文件以便于更好地收集一些资料信息等等.至于为何要把上传组 ...

  9. React项目中使用wangeditor以及扩展上传附件菜单

    在最近的工作中需要用到富文本编辑器,结合项目的UI样式以及业务需求,选择了wangEditor.另外在使用的过程中发现wangEditor只有上传图片和视频的功能,没有上传文本附件的功能,所以需要对其 ...

随机推荐

  1. HDU 1166 敌兵布阵【分块】

    Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任 ...

  2. 算法复习——有源汇上下界可行流(bzoj2396)

    题目: Description We are supposed to make a budget proposal for this multi-site competition. The budge ...

  3. 【2018.10.20】noip模拟赛Day3 二阶和

    今年BJ省选某题的弱化版…… 这看起来就没那么难了,有几种方法维护,这里提两种. 第一种(傻逼的我写的) 维护 一维&二维前缀和. 对于一个长度为$m$的序列$b_1,b_2,...,b_m$ ...

  4. Spring JdbcTemplate 查询方法中的RowMapper实现汇总

    实现一.在内部建立内联类实现RowMapper接口 package hysteria.contact.dao.impl; import java.sql.ResultSet; import java. ...

  5. request,response,session,cookie,application

    A:request 客服端向服务器端请求 JAVA讲究封装,所以Request也是某个东西的封装,到底是什么东西呢? 按字面意思:请求! 从Http协议说起,当你发一个请求到服务端的时候,你会把一些信 ...

  6. response.sendRedirect()使用注意事项

    用response.sendRedirect做转向其实是向浏览器发送一个特殊的Header,然后由浏览器来做转向,转到指定的页面,所以用sendRedirect时,浏览器的地址栏上可以看到地址的变化. ...

  7. OTOCI(bzoj 1180)

    Description 给出n个结点以及每个点初始时对应的权值wi.起始时点与点之间没有连边.有3类操作: 1.bridge A B:询问结点A与结点B是否连通.如果是则输出“no”.否则输出“yes ...

  8. 联合权值(codevs 3728)

    Description 无向连通图 G 有 n 个点,n−1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi,每条边的长度均为 1.图上两点 (u,v) 的距离定义为 u 点到 v ...

  9. 搭建Redis环境以及所遇问题(CentOS7+Redis 3.2.8)

    一.安装步骤 1. 首先需要安装gcc,把下载好的redis-3.2.8-rc2.tar.gz 放到/usr/local文件夹下 2. 进行解压 tar -zxvf redis-3.2.8-rc2.t ...

  10. luogu P1032 字串变换

    题目描述 已知有两个字串 A, B 及一组字串变换的规则(至多6个规则): A1 -> B1 A2 -> B2 规则的含义为:在 A$中的子串 A1 可以变换为 B1.A2 可以变换为 B ...