好记性不如烂笔头,今天把 react-native-image-crop-picker 总结下。废话不多说,开始。
1.执行下面命令行:
npm i react-native-image-crop-picker --save
react-native link react-native-image-crop-picker
安卓配置
1.在android/build.gradle添加以下代码
allprojects {
repositories {
mavenLocal()
jcenter()
maven { url "$rootDir/../node_modules/react-native/android" }
//我是要添加的...
maven { url "https://jitpack.io" }
}
}
2.在android/app/build.gradle添加以下代码
android {
...
defaultConfig {
//我是要添加的....
vectorDrawables.useSupportLibrary = true
...
}
...
}
3.在android/app/src/main/AndroidManifest.xml添加以下代码
Ios配置
1.在info.plist内添加以下内容
Privacy - Photo Library Usage Description
Privacy - Camera Usage Description
2.在target添加以下内容General添加以下内容
完整代码借用一下官方的
import React, {Component} from 'react';
import {
View, Text, StyleSheet, ScrollView, Alert,
Image, TouchableOpacity, NativeModules, Dimensions
} from 'react-native';
import Video from 'react-native-video';
var ImagePicker = NativeModules.ImageCropPicker;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
button: {
backgroundColor: 'blue',
marginBottom: 10
},
text: {
color: 'white',
fontSize: 20,
textAlign: 'center'
}
});
export default class App extends Component {
constructor() {
super();
this.state = {
image: null,
images: null
};
}
pickSingleWithCamera(cropping) {
ImagePicker.openCamera({
cropping: cropping,
width: 500,
height: 500,
includeExif: true,
}).then(image => {
console.log('received image', image);
this.setState({
image: {uri: image.path, width: image.width, height: image.height},
images: null
});
}).catch(e => alert(e));
}
pickSingleBase64(cropit) {
ImagePicker.openPicker({
width: 300,
height: 300,
cropping: cropit,
includeBase64: true,
includeExif: true,
}).then(image => {
console.log('received base64 image');
this.setState({
image: {uri: `data:${image.mime};base64,`+ image.data, width: image.width, height: image.height},
images: null
});
}).catch(e => alert(e));
}
cleanupImages() {
ImagePicker.clean().then(() => {
console.log('removed tmp images from tmp directory');
}).catch(e => {
alert(e);
});
}
cleanupSingleImage() {
let image = this.state.image || (this.state.images && this.state.images.length ? this.state.images[0] : null);
console.log('will cleanup image', image);
ImagePicker.cleanSingle(image ? image.uri : null).then(() => {
console.log(`removed tmp image ${image.uri} from tmp directory`);
}).catch(e => {
alert(e);
})
}
cropLast() {
if (!this.state.image) {
return Alert.alert('No image', 'Before open cropping only, please select image');
}
ImagePicker.openCropper({
path: this.state.image.uri,
width: 200,
height: 200
}).then(image => {
console.log('received cropped image', image);
this.setState({
image: {uri: image.path, width: image.width, height: image.height, mime: image.mime},
images: null
});
}).catch(e => {
console.log(e);
Alert.alert(e.message ? e.message : e);
});
}
pickSingle(cropit, circular=false) {
ImagePicker.openPicker({
width: 300,
height: 300,
cropping: cropit,
cropperCircleOverlay: circular,
compressImageMaxWidth: 640,
compressImageMaxHeight: 480,
compressImageQuality: 0.5,
compressVideoPreset: 'MediumQuality',
includeExif: true,
}).then(image => {
console.log('received image', image);
this.setState({
image: {uri: image.path, width: image.width, height: image.height, mime: image.mime},
images: null
});
}).catch(e => {
console.log(e);
Alert.alert(e.message ? e.message : e);
});
}
pickMultiple() {
ImagePicker.openPicker({
multiple: true,
waitAnimationEnd: false,
includeExif: true,
}).then(images => {
this.setState({
image: null,
images: images.map(i => {
console.log('received image', i);
return {uri: i.path, width: i.width, height: i.height, mime: i.mime};
})
});
}).catch(e => alert(e));
}
scaledHeight(oldW, oldH, newW) {
return (oldH / oldW) * newW;
}
renderVideo(video) {
return (
);
}
renderImage(image) {
return
}
renderAsset(image) {
if (image.mime && image.mime.toLowerCase().indexOf('video/') !== -1) {
return this.renderVideo(image);
}
return this.renderImage(image);
}
render() {
return (
{this.state.image ? this.renderAsset(this.state.image) : null}
{this.state.images ? this.state.images.map(i => {this.renderAsset(i)} ) : null}
this.pickSingleWithCamera(false)} style={styles.button}>
Select Single With Camera
this.pickSingleWithCamera(true)} style={styles.button}>
Select Single With Camera With Cropping
this.pickSingle(false)} style={styles.button}>
Select Single
this.cropLast()} style={styles.button}>
Crop Last Selected Image
this.pickSingleBase64(false)} style={styles.button}>
Select Single Returning Base64
this.pickSingle(true)} style={styles.button}>
Select Single With Cropping
this.pickSingle(true, true)} style={styles.button}>
Select Single With Circular Cropping
Select Multiple
Cleanup All Images
Cleanup Single Image
);
}
}
属性:
参数 | 类型 | 描述 |
---|---|---|
cropping | bool | (default false) 是否打开裁剪 |
width | number | 与cropping=true一起使用的,裁剪后的宽度 |
height | number | 与cropping=true一起使用的,裁剪后的高度 |
multiple | bool (default false) | 启用或禁用多个图像选择 |
includeBase64 | bool (default false) | 启用或禁用使用图像返回base64数据 |
cropperActiveWidgetColor (android only) | string (default "#424242") | 裁剪图像时,确定工具栏和其他UX元素的颜色。 |
cropperStatusBarColor (android only) | string (default "#424242") | 裁剪图像时,决定状态栏StatusBar颜色。 |
cropperToolbarColor (android only) | string (default #424242) | 裁剪图像时,决定状态栏Toolbar颜色. |
cropperCircleOverlay | bool (default false) | 裁剪图像时候,是否打开圆形裁剪覆盖(注:我的理解是圆形裁剪框) |
maxFiles (ios only) | number (default 5) | 最多能够选取的文件数,配合multiple=true |
waitAnimationEnd (ios only) | bool (default true) | Promise will resolve/reject once ViewController completion block is called |
compressVideo (ios only) | bool (default true) | 选择视频时,压缩它并将其转换为mp4 |
smartAlbums (ios only) | array (default ['UserLibrary', 'PhotoStream', 'Panoramas', 'Videos', 'Bursts']) | (列出可供选择的智能相册)List of smart albums to choose from |
useFrontCamera (ios only) | bool (default false) | 相机打开时是否定义文字字体 |
compressVideoPreset (ios only) | string (default MediumQuality) | 选择预设一个视频压缩度 |
compressImageMaxWidth | number (default none) | 压缩图像最大宽度 |
compressImageMaxHeight | number (default none) | 压缩图像最大高度 |
compressImageQuality | number (default 1) | 压缩图片的质量(从0到1,1是最大质量) |
loadingLabelText (ios only) | string (default "Processing assets...") | 图片加载时候文字显示 |
mediaType | string (default any) | 选择一个媒体类型 photo/video/any/ |
showsSelectedCount (ios only) | bool (default true) | 是否显示选中图片的数量 |
showCropGuidelines (android only) | bool (default true) | 裁剪过程中是否显示3x3的网格线 |
hideBottomControls (android only) | bool (default false) | 是否展示底部控件 |
enableRotationGesture (android only) | bool (default false) | 是否可以通过手势来旋转图像。 |
返回值:
参数 | 类型 | 描述 |
---|---|---|
path | string | 选中文件的位置 |
width | number | 选中文件的宽度 |
height | number | 选中文件的高度 |
mime | string | 选中图片的MIME类型(image/jpeg, image/png) |
size | number | 所选图像大小(以字节为单位) |
data | base64 | (选择文件以base64表示)Optional base64 selected file representation |
问题:1.
解决方案:
在android/build.gradle添加以下代码:
maven { url "https://jitpack.io" }
ios打开多次打开相册死机问题
pickSingleBase64(cropit) {
this._timer=setInterval(()=>{
ImagePicker.openPicker({
width: 300,
height: 300,
cropping: cropit,
multiple: true,
includeBase64: true,
includeExif: true,
compressImageQuality:0.3 //图片压缩,1位最高质量
}).then(image => {
const List=[];
// console.log('44444',image);
for (let i=0; i0){
this.setState({
image:(this.state.image.concat(List)).slice(0,3)
})
}
}).catch(e => console.log(e));
this._timer&&clearInterval(this._timer);
},1000);
}
//在最外层加一个延时器即可!!!!!
亲测没有问题,觉得有用的小伙伴点个小红心就行,么么哒。