随着互联网的发展,图片在各种网站和应用中铺天盖地,运营人员在后台管理系统中上传图片时常常忽略的图片的体积大小,随之产生的带宽和服务器容量也大大增加,图片压缩的需求随之产生。
常见的压缩图片的方案有:
1. 将图片压缩后再上传;
2. 利用图床(图片服务器)压缩图片;
虽然图片压缩过后体积会小一些,但是为了加载的更快,常常还会采用以下一些配套加载方案。
1. 图片懒加载,延迟加载甚至不加载,可以更快的渲染出页面轮廓,同时也可以减少并发请求数,有利于服务端;
2. 图片预加载,提前加载图片,当用户需要查看时可直接从本地缓存中渲染;
3. 图片流式加载,本质上来说这个也是属于预加载的一种,它是将大量的图片分页进行预加载,抖音的滑屏滚动就是这种方式;
前端实现图片压缩的基本思路为:在上传图片时,将file转换成image对象
, 然后再利用canvas及其 api
将图片压缩成指定体积。
首先将file转换成image对象,
这里我们用到了FileReader这个API。
// 压缩前将file转换成image对象
function readImg(file) {return new Promise((resolve, reject) => {const image = new Image();const reader = new FileReader();reader.onload = function (e) {image.src = e.target.result};reader.onerror = function (e) {reject(e)};reader.readAsDataURL(file);image.onload = function () {resolve(image)};image.onerror = function (e) {reject(e)};})
}
以下是图片压缩方法的代码实现:
/*** @param img 被压缩的img对象* @param type 压缩后转换的文件类型* @param mx 触发压缩的图片最大宽度限制* @param mh 触发压缩的图片最大高度限制* @param quality 图片质量
*/function compressImg(img, type, mx, mh, quality) {return new Promise((resolve, reject) => {const canvas = document.createElement('canvas');const context = canvas.getContext('2d');const {originWidth, originHeight} = img;// 最大尺寸const maxWidth = mx;const maxHeight = mh;// 目标尺寸let targetWidth = originWidth;let targetHeight = originHeight;if (originWidth > maxWidth || originHeight > maxHeight){if (originWidth / originHeight > 1) {// 图片宽targetWidth = maxWidthtargetHeight = Math.round(maxWidth * (originHeight / originWidth))} else {// 图片高targetHeight = maxHeighttargetWidth = Math.round(maxHeight * (originWidth / originHeight))}};canvas.width = targetWidth;canvas.height = targetHeight;context?.clearRect(0, 0, targetWidth, targetHeight);// 图片绘制context?.drawImage(img, 0, 0, targetWidth, targetHeight);canvas.toBlob(function (blob) {resolve(blob)}, type || 'image/png', quality?quality:1);})
}