需求是老师点评,需要上传图片,但是图片太大了,进行压缩,因为是h5 所以自带的压缩不支持,搜了很多文档,结合了一下,最后艰难的完成这个功能,记录一下。
架构是uniapp uview2 上传组件upload,上传代码是uni.uploadFile,后端是gofastdfs的上传代码,主要是把图片从前端压缩后传给后端上传,返回文件地址。
上传组件upload 方法就是uview2官网上的上传例子
<u-upload
:fileList="fileList6"
@afterRead="afterRead"
@delete="deletePic"
name="6"
multiple
:maxCount="6"
:previewFullImage="true"
width="100"
height="100"
:custom-btn="true"
></u-upload>
上传方法
async afterRead(event) {
console.log(event);
if(event.name == 2){
console.log('上传视频功能升级中');
return;
}
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this[`fileList${event.name}`].length
lists.map((item) => {
this[`fileList${event.name}`].push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
console.log("lists[i].url:")
console.log(lists[i].url)
console.log(lists[i]);
// Blob Url 转Blob
const blod = await this.fetchBlobFromUrl(lists[i].url);
console.log("this is blob:")
console.log(blod) // Blob {size: 1138, type: 'image/png'}
//compressImage 参数是file 或者blob
const comblod = await this.compressImage(blod,lists[i]);
console.log("this is comblod:");
console.log(comblod);
// const result = JSON.parse(await this.uploadFilePromise(lists[i].url))
const result = JSON.parse(await this.uploadFilePromise(comblod,lists[i]))
let item = this[`fileList${event.name}`][fileListLen]
this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result.data.url,
fileId:result.data.fileId
}))
this.fileIdList.push(result.data.fileId);
fileListLen++
}
}
//Blob Url 转Blob
fetchBlobFromUrl(blobUrl) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', blobUrl, true);
xhr.responseType = 'blob';
xhr.onload = function () {
if (xhr.status === 200) {
const blob = xhr.response;
console.log("blob--->");
console.log(blob);
console.log("xhr.response --->");
console.log(xhr.response);
resolve(blob);
} else {
reject(new Error(`Failed to fetch blob: ${xhr.statusText}`));
}
};
xhr.onerror = function () {
reject(new Error('Network error'));
};
xhr.send();
})
}
// 压缩图片方法
compressImage(filepath,file) {
console.log(filepath);
console.log(file);
const promise = new Promise((resolve, reject) => {
new Compressor(filepath, {
quality: 0.6, // 压缩质量,默认0.6
convertSize: 1024 * 100, // 转换的图片大小,默认1024 * 100,即100kb
success: (result) => {
// 压缩成功后的图片路径result.target为压缩后的图片路径,result.blob为压缩后的图片blob对象,可以用来上传到服务器
console.log('Compressed image path:', result); // 或者上传result.blob到服务器
// this.uploadImage(result.target); // 可以选择上传压缩后的图片或者使用blob对象上传
// let newfile = new File([result],file.name,{type:file.type});
// console.log(newfile)
let url = URL.createObjectURL(result);
resolve(url);
},
error(err) {
console.log(err);
console.error('Something went wrong:');
},
// 其他配置...
});
});
return promise;
},
//上传方法
// uploadFile 这里filepath需要blob url ,后端MultipartFile接收,不压缩后端能接收到filename,压缩后收不到,找不到解决方法为不知道为什么,前端传文件名称
uploadFilePromise(url,file) {
console.log("vuex_token");
const vuex_token = storage.get("AccessToken");
const studentId = this.formData.studentId;
console.log(url);
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: '192.168.10.198:81/dev-api/upload/upload/lessonFileUpload', // 仅为示例,非真实的接口地址
filePath: url,
name: 'file',
formData: {
studentId: studentId,
fileName:file.name
},
header: {
Authorization: vuex_token
},
success: (res) => {
setTimeout(() => {
resolve(res.data)
}, 1000)
}
});
})
},
导入类
npm install compressorjs
引入
import Compressor from 'compressorjs';
后端
@PostMapping("/lessonFileUpload")
public AjaxResult lessonFileUpload(@RequestParam("file") MultipartFile mulFile,
@RequestParam(value = "title",required = false) String title,
@RequestParam(value = "content",required = false) String content,
@RequestParam(value = "photography",required = false) String photography,
@RequestParam(value = "design",required = false) String design,
@RequestParam(value = "destypeign",required = false) String destypeign,
@RequestParam(value = "type",required = false) String type,
@RequestParam(value = "keyword",required = false) String keyword,
@RequestParam(value = "classId",required = false) String classId,
@RequestParam(value = "deptId",required = false) String deptId,
@RequestParam(value = "studentId",required = false) String studentId,
@RequestParam(value = "fileName",required = false) String fileName
)