如何使用JavaScript调整图片大小 压缩上传图片加快加载速度
浏览器端
<input type="file">选图即时压缩方案 针对12MB左右的常规拍摄图片,用浏览器原生Canvas API做前端压缩,不需要上传到服务端处理,选完图就能拿到压缩后的文件,一般能把体积压到原大小的10%-20%,加载速度提升5-10倍,全程用户无感知。
核心压缩逻辑
- 格式优先选WebP:同等画质下体积比JPG小40%以上,比PNG小70%,目前所有主流浏览器均已支持,不支持的场景自动兜底JPG即可
- 控制导出质量:Canvas导出图片时设置0.6-0.8的质量参数,这个区间人眼几乎感知不到画质差异,体积缩减收益最高,参数低于0.5会出现明显的色块模糊
- 限制最大边长:手机、相机直出的图片长边普遍在4000像素以上,网页端展示场景下长边控制在1920像素足够满足高清屏需求,这一步通常能砍掉60%以上的冗余像素
- 自动剥离冗余数据:Canvas导出的图片默认不会携带EXIF拍摄参数、定位信息、缩略图等非展示必要数据,这部分经常能占几百KB的体积
可直接运行的实现代码
<!-- 页面文件选择控件 --> <input type="file" id="imgUpload" accept="image/*"> <script> const uploadInput = document.getElementById('imgUpload') uploadInput.addEventListener('change', async (e) => { const originalFile = e.target.files[0] if (!originalFile) return // 加载选中的图片文件为Image实例 const img = await loadImage(originalFile) // 计算压缩后尺寸,长边最大限制为1920像素 const maxEdge = 1920 let { width, height } = img if (width > height && width > maxEdge) { height = height * (maxEdge / width) width = maxEdge } else if (height > maxEdge) { width = width * (maxEdge / height) height = maxEdge } // Canvas重绘实现压缩 const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') canvas.width = width canvas.height = height ctx.drawImage(img, 0, 0, width, height) // 优先导出WebP格式,质量设为0.7 const exportMime = 'image/webp' const exportQuality = 0.7 canvas.toBlob((compressedBlob) => { // 此处拿到的compressedBlob就是压缩后的文件,可直接用于预览/上传 // 转为File对象和原文件结构完全一致 const compressedFile = new File([compressedBlob], originalFile.name.replace(/\.\w+$/, '.webp'), { type: exportMime, lastModified: Date.now() }) console.log('原文件大小:', (originalFile.size / 1024 / 1024).toFixed(2) + 'MB') console.log('压缩后大小:', (compressedFile.size / 1024 / 1024).toFixed(2) + 'MB') // 后续直接写预览、上传逻辑即可 }, exportMime, exportQuality) }) // 工具方法:File对象转Image实例 function loadImage(file) { return new Promise((resolve, reject) => { const img = new Image() img.src = URL.createObjectURL(file) img.onload = () => { URL.revokeObjectURL(img.src) // 释放临时内存避免泄漏 resolve(img) } img.onerror = reject }) } </script>
适配调整提示
- 如果需要兼容极低版本浏览器,把导出格式改成
image/jpeg,质量参数调到0.75即可,不影响核心压缩逻辑 - 处理带透明通道的PNG图片时,不要转JPG(会丢失透明通道填充黑底),优先用WebP导出,兜底场景用PNG无损压缩
- 高画质要求场景(比如摄影作品、设计素材上传),可以把最大边长调整到2560像素,质量参数调到0.85,压缩后体积依然能比原图小60%左右
- 如果遇到iOS拍摄图片上传后旋转的问题,是因为图片EXIF里带了方向标记,在Canvas绘制前读取EXIF的orientation值,对应旋转画布校正方向即可
内容的提问来源于stack exchange,提问作者Amr Khaled
相关产品推荐
相关产品推荐

