您现在的位置是:首页 > Javascript
当前栏目
前端图片压缩方案及代码实现
2023-03-07 09:09:35 时间
1. 为什么要进行图片压缩?
随着互联网的发展,图片在各种网站和应用中铺天盖地,运营人员在后台管理系统中上传图片时常常忽略的图片的体积大小,随之产生的带宽和服务器容量也大大增加,图片压缩的需求随之产生。
常见的压缩图片的方案有:
1. 将图片压缩后再上传;
2. 利用图床(图片服务器)压缩图片;
虽然图片压缩过后体积会小一些,但是为了加载的更快,常常还会采用以下一些配套加载方案。
1. 图片懒加载,延迟加载甚至不加载,可以更快的渲染出页面轮廓,同时也可以减少并发请求数,有利于服务端;
2. 图片预加载,提前加载图片,当用户需要查看时可直接从本地缓存中渲染;
3. 图片流式加载,本质上来说这个也是属于预加载的一种,它是将大量的图片分页进行预加载,抖音的滑屏滚动就是这种方式;
2. 前端图片压缩方案
前端实现图片压缩的基本思路为:在上传图片时,将file转换成image对象
, 然后再利用canvas及其 api
将图片压缩成指定体积。
3. 前端图片压缩方案代码实现
首先将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 = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
// 图片高
targetHeight = maxHeight
targetWidth = 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);
})
}
相关文章
- 鲜为人知但很有用的 HTML 属性
- 翻转再翻转!有意思的水平横向溢出滚动
- 自定义计数器小技巧!CSS 实现长按点赞累加动画
- 过五关!React高频面试题指南
- 软件开发中的十个认知偏差
- 不需要 JS!仅用 CSS 也能达到监听页面滚动的效果!
- 一文读懂TypeScript类型兼容性
- Vue 的响应式原则与双向数据绑定
- 快速掌握 TypeScript 新语法:Infer Extends
- JWT教你如何证明你是我的人!
- 一篇带给你 V8 GC 的实现
- 面试官:请使用JS完成一个LRU缓存?
- 通过可视化来学习JavaScript事件循环
- 新的跨域策略:使用 COOP、COEP 为浏览器创建更安全的环境
- 为什么有人说 vite 快,有人却说 vite 慢?
- 种草 Vue3 中几个好玩的插件和配置
- 超全面的前端工程化配置指南
- Vue 状态管理未来样子
- Volatile关键字能保证原子性么?
- 面试突击:SpringBoot 有几种读取配置文件的方法?