压缩图片
大约 3 分钟约 795 字
//压缩图片
onChange = (files, type, index) => {
if (type === 'add') {
let imageList = []
files.map((item, index) => {
return lrz(item.url, {
quality: 0.7
}).then(rst => {
// 处理成功会执行
imageList.push(rst.base64)
this.setState({ imagesrc: imageList })
})
})
} else {
this.setState({ imagesrc: [] })
}
this.setState({ files })
}
;(function () {
var coverImage = document.querySelector('<div id="coverImage">file</div>')
//图片压缩
coverImage.onchange = function () {
lrz(this.files[0], { width: 640 }, function (results) {
// 你需要的数据都在这里,可以以字符串的形式传送base64给服务端转存为图片。
var base64 = results.base64
function base64UrlToBlob(base64) {
var bytes = window.atob(base64.split(',')[1]) //去掉url的头,并转换为byte
//处理异常,将ascii码小于0的转换为大于0
var ab = new ArrayBuffer(bytes.length)
var ia = new Uint8Array(ab)
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i)
}
return new Blob([ab], { type: 'image/jpg' }) //return Blob对象
}
var formData = new FormData($('#toPic')[1])
var blob = base64UrlToBlob(base64)
console.log(blob)
formData.append('coverImage', blob)
$.ajax({
url: 'xxx',
type: 'POST',
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function (json) {
console.log(json)
}
})
setTimeout(function () {
demo_report('预压的图片', base64, base64.length * 0.5)
}, 100)
})
}
})()
将 blob 对象转二进制 buffer
在客户端,返回的数据是 blob 二进制数据,那么怎么将它向客户端进行解压呢?最后通过 renderer 对象成功解决:
var render = new FileReader()
render.onloadend = function () {
var ms = pako.inflate(render.result, {
to: 'string'
})
var msg = JSON.parse(ms)
if (msg.ping) {
that.websocket.send(
JSON.stringify({
pong: msg.ping
})
)
} else if (msg.tick) {
var attr = msg.ch.split('.')[1]
document.querySelector('.' + that.name + attr).innerHTML = parseFloat(
msg.tick.close
)
}
}
render.readAsBinaryString(e.data)
url 转 base64 base64 转 blob
function getBase64(img) {
//传入图片路径,返回base64
function getBase64Image(img, width, height) {
//width、height调用时传入具体像素值,控制大小 ,不传则默认图像大小
var canvas = document.createElement('canvas')
canvas.width = width ? width : img.width
canvas.height = height ? height : img.height
var ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
var dataURL = canvas.toDataURL()
return dataURL
}
var image = new Image()
image.src = img
var deferred = $.Deferred()
if (img) {
image.onload = function () {
deferred.resolve(getBase64Image(image)) //将base64传给done上传处理
}
return deferred.promise() //问题要让onload完成后再return sessionStorage['imgTest']
}
}
function base64toBlob(dataurl) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
}
BASE64 加密字符串,当编码的字节较长时,encode 出来的字符串会自动加入\r\n 进行自动换行。针对这个问题,原因是 rfc 规范规定 76 个字符换一次行。我们可以使用 replaceAll("\r\n", "")来进行替换。替换后,没问题了。代码示例如下:
oldphoto64code = base64encode.encode(b).replaceAll('\r\n', '')
vue 图片压缩
// unit.js
const unit = {
/**
* blob转file
*/
blobToFile: (blob, fileName, mime) => {
// ios heic 格式图片替换
fileName = fileName.replace(".HEIC", ".jpg").replace(".heic", ".jpg");
return new File([blob], fileName, {
type: mime,
lastModified: Date.now(),
});
},
};
export default unit;
/**
* desc: 图片压缩
*/
import lrz from "lrz";
import unit from "./unit";
const compressImg = {
getSize: size => {
const fileSize = parseFloat(parseInt(size) / 1024 / 1024).toFixed(2);
return fileSize;
},
resize: (file, options) => {
return new Promise((resolve, reject) => {
if (!file) {
return reject(new Error("请先选择图片文件"));
}
const fileSize = compressImg.getSize(file["size"]);
// 小于1M直接返回不做处理
if (fileSize <= 1) {
return resolve({ file: file });
}
if (!options) {
// 大于1M小于5M
if (fileSize > 1 && fileSize <= 5) {
options = { quality: 0.92 }; // canvas默认值
}
// 大于5M小于10M
if (fileSize > 5 && fileSize <= 10) {
options = { quality: 0.9 }; // canvas默认值
}
// 大于10M
if (fileSize > 10) {
options = { quality: 0.85 };
}
}
return lrz(file, options).then(res => {
const fileName = res.origin.name;
const mime = res.origin.type;
const newSize = compressImg.getSize(res.fileLen);
// 大于10M
if (newSize > 10) {
return reject(new Error("上传文件不能大于10M"));
}
const newFile = unit.blobToFile(res.file, fileName, mime);
resolve({ file: newFile });
}, reject);
});
},
};
export default compressImg;