在用React native做项目的时候,遇到了照片的压缩上传问题。在很多RN技术交流群中,询问到的结果也是让用原生。但这里就遇到了RN和原生之间的兼容问题。
在不懈努力之下,终于找到了一个ImagePicker这个组件。当执行这个组件时,可以开启相机,拍照后就把图片改成您设置的最大宽或者高 像素的图片,另一个属性会自动适应。例如:
openCamera() { //在开启相机,拍照时,把照片压缩,而options中的maxWidth,maxHeight为设置的宽和高的最大像素 const options = { title:null, cancelButtonTitle:'取消', takePhotoButtonTitle:'拍照', chooseFromLibraryButtonTitle:'选择相册', quality: 1.0, maxWidth: 500, maxHeight: 500, storageOptions: { skipBackup: true }, } //在ImagePicker组件的launchCamera方法中,加入options参数,就可将图片压缩为options中相应像素的照片 ImagePicker.launchCamera(options, (response) => { if (response.didCancel) { return; } else { let dataArray = this.state._data; dataArray.push(response.uri); photoUrls.push(response.uri); this.setState({ _data: dataArray, }); this.props.callback(this.state._data); } }); }
当然,图片的URI也会相应的保存进数组中,以供您上传到服务器。
在网上ImagePacker这个组件的options中的属性还有很多,现在贴出来(ImagePacker组件详细网址:https://www.npmjs.com/package/react-native-image-picker):
option | iOS | Android | Info |
---|---|---|---|
title | OK | OK | Specify null or empty string to remove the title |
cancelButtonTitle | OK | OK | Specify null or empty string to remove this button (Android only) |
takePhotoButtonTitle | OK | OK | Specify null or empty string to remove this button |
chooseFromLibraryButtonTitle | OK | OK | Specify null or empty string to remove this button |
customButtons | OK | OK | An array containing objects with the name and title of buttons |
cameraType | OK | - | 'front' or 'back' |
mediaType | OK | OK | 'photo', 'video', or 'mixed' on iOS, 'photo' or 'video' on Android |
maxWidth | OK | OK | Photos only |
maxHeight | OK | OK | Photos only |
quality | OK | OK | 0 to 1, photos only |
videoQuality | OK | OK | 'low', 'medium', or 'high' on iOS, 'low' or 'high' on Android |
durationLimit | OK | OK | Max video recording time, in seconds |
rotation | - | OK | Photos only, 0 to 360 degrees of rotation |
allowsEditing | OK | - | bool - enables built in iOS functionality to resize the image after selection |
noData | OK | OK | If true, disables the base64 data field from being generated (greatly improves performance on large photos) |
storageOptions | OK | OK | If this key is provided, the image will be saved in your app's Documents directory on iOS, or your app's Pictures directory on Android (rather than a temporary directory) |
storageOptions.skipBackup | OK | - | If true, the photo will NOT be backed up to iCloud |
storageOptions.path | OK | - | If set, will save the image at Documents/[path]/ rather than the root Documents |
storageOptions.cameraRoll | OK | OK | If true, the cropped photo will be saved to the iOS Camera Roll or Android DCIM folder. |
storageOptions.waitUntilSaved | OK | - | If true, will delay the response callback until after the photo/video was saved to the Camera Roll. If the photo or video was just taken, then the file name and timestamp fields are only provided in the response object when this AND cameraRoll are both true. |
permissionDenied.title | - | OK | Title of explaining permissions dialog. By default Permission denied . |
permissionDenied.text | - | OK | Message of explaining permissions dialog. By default To be able to take pictures with your camera and choose images from your library. . |
permissionDenied.reTryTitle | - | OK | Title of re-try button. By default re-try |
permissionDenied.okTitle | - | OK | Title of ok button. By default I'm sure |
这个组件很强大,需要用这个组件其他的方法,可以自行去组件官网或https://www.npmjs.com/package/react-native-image-picker去自行查找
现贴一个前辈大神写的关于React Native拍照相关事件的代码,记录一下,方便后面的学习,使用
selectPhotoTapped() { const options = { title:null, cancelButtonTitle:'取消', takePhotoButtonTitle:'拍照', chooseFromLibraryButtonTitle:'选择相册', quality: 1.0, maxWidth: 500, maxHeight: 500, storageOptions: { skipBackup: true }, } // 如果直接调取拍照, 不显示弹出框, 不然显示弹出选择 if (this.props.notNeedLibraryButton) { ImagePicker.launchCamera(options, (response) => { console.log('Response = ', response); if (response.error === 'Camera permissions not granted') { Alert.alert( '没有权限', '相机权限未开启,请到设置中开启!' ); } // 如果是iOS,没有fileName if (response.uri && Platform.OS !== 'android') { // 从uri截取fileName const temp = response.uri.split('/'); response.fileName = temp[temp.length - 1]; // 去掉 file:// response.uri = response.uri.substring(7); } // 是否竖直拍摄还是横着, 横着就旋转照片, true 横着拍的照片, false 竖着拍的照片 const rotationPic = response.height - response.width < 0; // options.storageOptions=true; if (response.didCancel) { console.log('User cancelled photo picker'); } else if (response.error) { console.log('ImagePicker Error: ', response.error); } else if (response.customButton) { console.log('User tapped custom button: ', response.customButton); } else { // 横着拍, 添加标识 rotation let theId = rotationPic? `rotation${response.fileName}` : response.fileName ; let newAddPic = [...this.state.newAddPic]; newAddPic.push(response.uri); let source = [{ url: response.uri,id: theId, name: theId }]; let length = [...this.state.avatarSource, ...source].length; if (length >= this.state.limitNumber ) { this.setState({ avatarSource: [...this.state.avatarSource, ...source], limitPic: true, },function() { this.props.code? this.props.onChange(this.state.avatarSource,this.props.code):this.props.onChange(this.state.avatarSource) }); }else { this.setState({ newAddPic: [...newAddPic], avatarSource: [...this.state.avatarSource, ...source], },function() { this.props.code? this.props.onChange(this.state.avatarSource,this.props.code):this.props.onChange(this.state.avatarSource) }); } } }); } else{ ImagePicker.showImagePicker(options, (response) => { console.log('Response = ', response); if (response.error === 'Camera permissions not granted') { Alert.alert( '没有权限', '相机权限未开启,请到设置中开启!' ); } // 如果是iOS,没有fileName if (response.uri && Platform.OS !== 'android') { // 从uri截取fileName const temp = response.uri.split('/'); response.fileName = temp[temp.length - 1]; // 去掉 file:// response.uri = response.uri.substring(7); } // 是否竖直拍摄还是横着, 横着就旋转照片 true 横着拍的照片, false 竖着拍的照片 const rotationPic = response.height - response.width < 0; console.log('rotationPic',rotationPic) // options.storageOptions=true; if (response.didCancel) { console.log('User cancelled photo picker'); } else if (response.error) { console.log('ImagePicker Error: ', response.error); } else if (response.customButton) { console.log('User tapped custom button: ', response.customButton); } else { // 横着拍, 添加标识 rotation let theId = rotationPic? `rotation${response.fileName}` : response.fileName ; let newAddPic = [...this.state.newAddPic]; newAddPic.push(response.uri); let source = [{ url: response.uri,id: theId, name: theId }]; let length = [...this.state.avatarSource, ...source].length; if (length >= this.state.limitNumber ) { this.setState({ avatarSource: [...this.state.avatarSource, ...source], limitPic: true, },function() { this.props.code? this.props.onChange(this.state.avatarSource,this.props.code):this.props.onChange(this.state.avatarSource) }); }else { this.setState({ newAddPic: [...newAddPic], avatarSource: [...this.state.avatarSource, ...source], },function() { this.props.code? this.props.onChange(this.state.avatarSource,this.props.code):this.props.onChange(this.state.avatarSource) }); } } }); } }