react native踩坑日记(7):头像编辑(拍照,选择图片,上传,毛玻璃背景效果实现方式)
最近继续迭代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