React native 照片压缩上传

在用React native做项目的时候,遇到了照片的压缩上传问题。在很多RN技术交流群中,询问到的结果也是让用原生。但这里就遇到了RN和原生之间的兼容问题。

在不懈努力之下,终于找到了一个ImagePicker这个组件。当执行这个组件时,可以开启相机,拍照后就把图片改成您设置的最大宽或者高 像素的图片,另一个属性会自动适应。例如:

openCamera() {
    //在开启相机,拍照时,把照片压缩,而options中的maxWidthmaxHeight为设置的宽和高的最大像素
    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):

Options

optioniOSAndroidInfo
titleOKOKSpecify null or empty string to remove the title
cancelButtonTitleOKOKSpecify null or empty string to remove this button (Android only)
takePhotoButtonTitleOKOKSpecify null or empty string to remove this button
chooseFromLibraryButtonTitleOKOKSpecify null or empty string to remove this button
customButtonsOKOKAn array containing objects with the name and title of buttons
cameraTypeOK-'front' or 'back'
mediaTypeOKOK'photo', 'video', or 'mixed' on iOS, 'photo' or 'video' on Android
maxWidthOKOKPhotos only
maxHeightOKOKPhotos only
qualityOKOK0 to 1, photos only
videoQualityOKOK'low', 'medium', or 'high' on iOS, 'low' or 'high' on Android
durationLimitOKOKMax video recording time, in seconds
rotation-OKPhotos only, 0 to 360 degrees of rotation
allowsEditingOK-bool - enables built in iOS functionality to resize the image after selection
noDataOKOKIf true, disables the base64 data field from being generated (greatly improves performance on large photos)
storageOptionsOKOKIf 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.skipBackupOK-If true, the photo will NOT be backed up to iCloud
storageOptions.pathOK-If set, will save the image at Documents/[path]/ rather than the root Documents
storageOptions.cameraRollOKOKIf true, the cropped photo will be saved to the iOS Camera Roll or Android DCIM folder.
storageOptions.waitUntilSavedOK-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-OKTitle of explaining permissions dialog. By default Permission denied.
permissionDenied.text-OKMessage of explaining permissions dialog. By default To be able to take pictures with your camera and choose images from your library..
permissionDenied.reTryTitle-OKTitle of re-try button. By default re-try
permissionDenied.okTitle-OKTitle 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)
            });
        }
      }
    });
  }

}

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值