在项目中,为了节约网络消耗,需要将文件进行压缩后上传服务端。
最开始考虑的是将文件压缩为 zip ,由服务端返回后前端 zip 再进行解压。但 zip 对小文件、图片、视频的压缩效果很差。所以需要多种压缩方式配合使用。
图像采用 canvas 有损压缩:
utils.dealImage = (base64, rate) => {
return new Promise((resolve, reject) => {
try {
let newImage = new Image();
let quality = rate || rate > 1 || rate <= 0 ? rate : 0.6; //压缩系数0-1之间
// newImage.setAttribute("crossOrigin", 'Anonymous'); //url为外域时需要
let imgWidth, imgHeight;
newImage.onload = function () {
imgWidth = this.width;
imgHeight = this.height;
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
canvas.width = imgWidth;
canvas.height = imgHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
let base64 = canvas.toDataURL("image/jpeg", quality); //压缩语句
resolve(base64);
}
newImage.src = base64;
} catch (err) {
reject(err);
}
})
}
// 文件 base64 压缩为 zip
utils.zip = (base64, fileName) => {
let inputBlob = utils.dataURItoBlob(base64);
let JSZip = require("jszip");
let zip = new JSZip();
zip.file(fileName, inputBlob, {
type: "blob"
});
// return a promise
return zip.generateAsync({
type: "blob",
compression: "DEFLATE", // force a compression for this file
compressionOptions: {
level: 9,
},
});
}
//blob to base64
utils.blobToDataURI = (blob) => {
return new Promise((resolve, reject) => {
try {
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function (e) {
resolve(e.target.result);
};
} catch (err) {
reject(err);
}
});
}
// base64 to blob
utils.dataURItoBlob = (dataURI) => {
let mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0]; // mime类型
let byteString = atob(dataURI.split(",")[1]); //base64 解码
let arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
let intArray = new Uint8Array(arrayBuffer); //创建视图
for (let i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], {
type: mimeString,
});
}
当你看清人们的真相,于是你知道了,你可以忍受孤独