react native踩坑日记(7):头像编辑(拍照,选择图片,上传,毛玻璃背景效果实现方式)

2022-07-25,,,,

最近继续迭代RN项目。也开始了继续踩坑,爬坑的“幸福生活”。上周刚完成头像设置的相关操作,大致分为毛玻璃背景,选择相册图片,拍照,图片裁剪,上传OSS(这一步主要是服务端配合,后面会详细说明)。由简到难,逐个讲解使用到的npm包和相关方法。

1:毛玻璃的效果实现

先看下效果图:
要实现这个的效果,我尝试了使用opacity,但是跟这个完全不搭边,所以就找了个npm包,@react-native-community/blur,文档跳转

yarn add @react-native-community/blur

or

npm install --save @react-native-community/blur

具体配置可查看对应文档。实测好用,这个没什么坑,装上就可以直接使用了。

2:选择图片,拍照使用

要实现这个,肯定想到的就是找依赖包了,我使用的是这个react-native-syan-image-picker,其中包括了裁剪返回base64编码的功能,比较实用。文档跳转

如果你们的项目中不需要裁剪可以换成这个react-native-image-picker,这个组件近期在维护,且使用起来相对简单一点,而且有对应操作的回调,方便出来用户操作。文档跳转,这个的使用方式就不说了,文档比较详细

安装依赖:

// Step 1 基于 npm
npm install react-native-syan-image-picker --save

// 或是 yarn
yarn add react-native-syan-image-picker

讲一个我开发过程中遇到的坑:RN0.6版本以后是不用link的,之前无脑按照文档安装依赖link某个依赖包后然后ios报错 react.h(大概内容,具体忘记了)找不到,然后按照提示unlink后即可正常运行,如果你使用的是0.6以上版本安装依赖后只需cd ios 执行pod install即可

上面是题外话。

然后具体的使用可查看官方文档。附上我使用的代码(不喜勿喷),因为使用相册和相机是两个方法所以需要一个参数来区分

// 选择图片或相册
  onClickChoosePicture = (comer) => {
    const options = {
      imageCount: 1, // 最大选择图片数目,默认6
      isCamera: true, // 是否允许用户在内部拍照,默认true
      isCrop: true, // 是否允许裁剪,默认false
      enableBase64: true,
      rotateEnabled: false,
    };
    let photoData = null;
    if (comer === 0) {
      ImagePicker.showImagePicker(options, (err, selectedPhotos) => {
        if (err) {
          console.log(err, 111);
          return;
        }
        photoData = selectedPhotos;
      });
    } else {
      ImagePicker.openCamera(options, (err, photos) => {
        if (err) {
          console.log(err);
          return;
        }
        photoData = photos;
        
      });
    }
  };

3: 文件转换

此依赖包返回数据并没有我们文件上传需要格式,所以我们需要获取到他返回的base64格式的字符串后在转码成文件ArrayBuffer格式。最终上传的是b。代码如下

说明:这里是把base64转换成了ArrayBuffer格式,只是转换成了可以适用于我们这个项目的文件格式,配上一张说明图

	var arr = base64String.split(',');
    var mime = arr[0].match(/:(.*?);/)[1];
    var bstr = base64Npm.encodeFromByteArray(arr[1]); // 真机
    // var bstr = atob(arr[1]); // 模拟机
    var n = bstr.length;
    let b = new ArrayBuffer(n);
    var u8arr = new Uint8Array(b);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }

4:文件上传

因为我们需要上传的OSS,所以接下来的操作就需要服务端的配合了,我们服务端大佬比较和蔼可亲积极帮助我完成这个功能,上传所需的签名啊,id啊,什么乱七八糟的东西他已经处理好拼接成对应的URL,在获取上传权限的时候返回给我了,所以我直接使用axios调用即可,代码如下:

axios
      .put(signUrl, b, config)
      .then((response) => {
        if (response.status === 200) {
          this.refreshUserInfo(id);
        }
      })
      .catch((err) => {
        Toast.showInfo('上传失败');
        console.log(err.message);
      });

上传文件有put,和post两种方式,所需参数也不同,所以第四步对你们应该没啥帮助,只是提供一种思路。毕竟也需要服务端配合。

5:正常js把base64转换为bolb和文件格式方法

const base64ToBlob = function(base64Data) {
      let arr = base64Data.split(','),
        fileType = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        l = bstr.length,
        u8Arr = new Uint8Array(l);

      while (l--) {
        u8Arr[l] = bstr.charCodeAt(l);
      }
      return new Blob([u8Arr], {
        type: fileType,
      });
    };
    // blob转file
    const blobToFile = function(newBlob, fileName) {
      newBlob.lastModifiedDate = new Date();
      newBlob.name = fileName;
      return newBlob;
    };

    const blob = base64ToBlob(base64String);
    const file = blobToFile(blob, '图片');

本文地址:https://blog.csdn.net/weixin_43827462/article/details/111832228

《react native踩坑日记(7):头像编辑(拍照,选择图片,上传,毛玻璃背景效果实现方式).doc》

下载本文的Word格式文档,以方便收藏与打印。