(转)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只有上传图片和视频的功能,没有上传文本附件的功能,所以需要对其 ...
随机推荐
- HDU 1166 敌兵布阵【分块】
Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任 ...
- 算法复习——有源汇上下界可行流(bzoj2396)
题目: Description We are supposed to make a budget proposal for this multi-site competition. The budge ...
- 【2018.10.20】noip模拟赛Day3 二阶和
今年BJ省选某题的弱化版…… 这看起来就没那么难了,有几种方法维护,这里提两种. 第一种(傻逼的我写的) 维护 一维&二维前缀和. 对于一个长度为$m$的序列$b_1,b_2,...,b_m$ ...
- Spring JdbcTemplate 查询方法中的RowMapper实现汇总
实现一.在内部建立内联类实现RowMapper接口 package hysteria.contact.dao.impl; import java.sql.ResultSet; import java. ...
- request,response,session,cookie,application
A:request 客服端向服务器端请求 JAVA讲究封装,所以Request也是某个东西的封装,到底是什么东西呢? 按字面意思:请求! 从Http协议说起,当你发一个请求到服务端的时候,你会把一些信 ...
- response.sendRedirect()使用注意事项
用response.sendRedirect做转向其实是向浏览器发送一个特殊的Header,然后由浏览器来做转向,转到指定的页面,所以用sendRedirect时,浏览器的地址栏上可以看到地址的变化. ...
- OTOCI(bzoj 1180)
Description 给出n个结点以及每个点初始时对应的权值wi.起始时点与点之间没有连边.有3类操作: 1.bridge A B:询问结点A与结点B是否连通.如果是则输出“no”.否则输出“yes ...
- 联合权值(codevs 3728)
Description 无向连通图 G 有 n 个点,n−1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi,每条边的长度均为 1.图上两点 (u,v) 的距离定义为 u 点到 v ...
- 搭建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 ...
- luogu P1032 字串变换
题目描述 已知有两个字串 A, B 及一组字串变换的规则(至多6个规则): A1 -> B1 A2 -> B2 规则的含义为:在 A$中的子串 A1 可以变换为 B1.A2 可以变换为 B ...