react-native-image-picker作為一個(gè)集成相機(jī)和相冊(cè)的功能的第三方庫(kù)却舀,因?yàn)槠涫褂孟鄬?duì)簡(jiǎn)單受到前端開(kāi)發(fā)人員的喜愛(ài)肾请。
react-native-image-picker使用
1, 首先,安裝下該插件寓免。
npm install react-native-image-picker@latest --save
2, 針對(duì)Android和iOS平臺(tái)分別進(jìn)行配置
android 平臺(tái)配置
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文件中添加權(quán)限:
<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()
這樣Android環(huán)境就配置好了牢撼。
iOS平臺(tái)配置
1,打開(kāi)Xcode打開(kāi)項(xiàng)目,點(diǎn)擊根目錄,右鍵選擇 Add Files to ‘XXX’,選中項(xiàng)目中的該路徑下的文件即可:node_modules -> react-native-image-picker -> ios -> select RNImagePicker.xcodeproj
2疑苫,添加成功后使用link命令:react-native link react-native-image-picker 熏版。
3纷责,打開(kāi)項(xiàng)目依次使用Build Phases -> Link Binary With Libraries將RNImagePicker.a添加到項(xiàng)目依賴。
4撼短,對(duì)于iOS 10+設(shè)備再膳,需要在info.plist中配置NSPhotoLibraryUsageDescription和NSCameraUsageDescription。
react-native-image-picker示例
為了項(xiàng)目使用的方便曲横,我們將其封裝為一個(gè)組件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: '圖片庫(kù)',
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} />
點(diǎn)擊上傳事件:
onFileUpload(file, fileName){
return this.props.uploadAvatar({
id: this.props.user.ID,
type:'logo',
obj:'user',
corpId: this.props.cropId
}, file, fileName)}
Action請(qǐng)求代碼:
function actions(dispatch) {
return {
fileUrl,fileName)=>dispatch(Actions.uploadAvatar(params, fileUrl,fileName))
}
}
actions中的uploadAvatar函數(shù)如下禾嫉。
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函數(shù)的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)
}
封裝上傳
如果上面的實(shí)現(xiàn)看的比較復(fù)雜灾杰,那么我們做如下的封裝:
let common_url = 'http://192.168.1.1:8080/'; //服務(wù)器地址
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=>{
//請(qǐng)求成功
if(res.header.statusCode == 'success'){
//這里設(shè)定服務(wù)器返回的header中statusCode為success時(shí)數(shù)據(jù)返回成功
upLoadImgUrl = res.body.imgurl; //服務(wù)器返回的地址
}else{
//服務(wù)器返回異常,設(shè)定服務(wù)器返回的異常信息保存在 header.msgArray[0].desc
console.log(res.header.msgArray[0].desc);
}
}).catch( err=>{
//請(qǐng)求失敗
})
參考:
http://blog.csdn.net/xiangzhihong8/article/details/72981936
http://blog.csdn.net/codetomylaw/article/details/52446786