答案:通过javaScript结合FileReader、canvas和Blob实现图片上传前的压缩与预览。首先利用FileReader读取图片并生成base64预览,再通过canvas绘制并缩放图片,调用toDataURL方法按质量压缩,最后将压缩后的base64数据用于预览或转为Blob上传,有效减少文件体积,提升上传效率与用户体验。

在前端开发中,图片上传前的压缩与预览功能非常实用,既能提升用户体验,又能减少服务器压力。使用 javascript 可以轻松实现这一功能,无需依赖后端处理。下面介绍如何通过原生 js 实现图片压缩与本地预览。
选择图片并生成预览
用户选择图片后,可以通过 FileReader 读取文件内容,并将结果设置为 img 标签的 src,实现即时预览。
示例代码:
<input type="file" id="upload" accept="image/*"> <img id="preview" src="" alt="预览图" style="max-width: 300px;"> <p><script> document.getElementById('upload').addEventListener('change', function(e) { const file = e.target.files[0]; if (!file) return;</p><p>const reader = new FileReader(); reader.onload = function(event) { document.getElementById('preview').src = event.target.result; }; reader.readAsDataURL(file); }); </script></p>
使用 Canvas 压缩图片
图片压缩的核心是利用 canvas 的绘图能力,将原始图片绘制到 canvas 上,并通过调整尺寸或质量来实现压缩。
立即学习“Java免费学习笔记(深入)”;
关键步骤:
- 创建一个 Image 对象加载原始图片
- 使用 canvas 绘制图片(可缩放)
- 调用 canvas.toDataURL(type, quality) 输出压缩后的 base64 数据
压缩函数示例:
function compressImage(file, maxWidth = 800, quality = 0.8) { return new Promise((resolve) => { const img = new Image(); const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); <pre class='brush:php;toolbar:false;'>const reader = new FileReader(); reader.onload = function(e) { img.src = e.target.result; }; img.onload = function() { let { width, height } = img; // 按最大宽度等比缩放 if (width > maxWidth) { height = Math.round((height * maxWidth) / width); width = maxWidth; } canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); // 导出压缩后的图片(JPEG 格式,质量 0.8) const compressedData = canvas.toDataURL('image/jpeg', quality); resolve(compressedData); }; reader.readAsDataURL(file);
}); }
完整使用流程
将选择、压缩和预览结合在一起:
document.getElementById('upload').addEventListener('change', async function(e) { const file = e.target.files[0]; if (!file) return; <p>// 压缩图片 const compressedDataURL = await compressImage(file, 800, 0.7);</p><p>// 显示预览 const preview = document.getElementById('preview'); preview.src = compressedDataURL;</p><p>// 如需上传,可将 base64 转为 Blob 发送 // const blob = dataURLToBlob(compressedDataURL); });</p>
如需将 base64 转为 Blob 用于上传:
function dataURLToBlob(dataurl) { const arr = dataurl.split(','); const mime = arr[0].match(/:(.*?);/)[1]; const bstr = atob(arr[1]); let n = bstr.length; const u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }
基本上就这些。通过 FileReader 预览,Canvas 压缩,再配合 Blob 转换,就能高效实现图片上传前的处理,既节省带宽,又提升响应速度。


