当前位置:首页 > 行业动态 > 正文

html5图片压缩上传

利用HTML5 Canvas压缩图片,减小体积后上传

HTML5图片压缩上传实现方案

核心原理

通过HTML5的FileReader读取图片二进制数据,结合Canvas对图像进行缩放处理,利用toBlob方法生成压缩后的图像文件,最终通过FormData提交到服务器。

实现步骤

  1. 文件选择与读取

    <input type="file" id="upload" accept="image/">
    const fileInput = document.getElementById('upload');
    fileInput.addEventListener('change', handleFile);
    function handleFile(e) {
      const file = e.target.files[0];
      if (!file) return;
      const reader = new FileReader();
      reader.onload = function(event) {
        const img = new Image();
        img.onload = function() {
          compressImage(img, file.type);
        };
        img.src = event.target.result;
      };
      reader.readAsDataURL(file);
    }
  2. 图像压缩处理

    function compressImage(img, type) {
      const canvas = document.createElement('canvas');
      let width = img.width;
      let height = img.height;
      // 计算压缩尺寸(保持比例)
      if (width > 1000) {
        width = 1000;
        height = (img.height  1000) / img.width;
      }
      canvas.width = width;
      canvas.height = height;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0, width, height);
      // 生成压缩文件
      canvas.toBlob(function(blob) {
        uploadFile(blob, type);
      }, type || 'image/jpeg', 0.7); // 质量参数0-1
    }
  3. 文件上传

    function uploadFile(blob, type) {
      const form = new FormData();
      form.append('file', blob, 'compressed.' + type.split('/')[1]);
      fetch('/upload', {
        method: 'POST',
        body: form,
        onUploadProgress: e => {
          console.log('上传进度:', Math.round(e.loaded  100 / e.total) + '%');
        }
      })
      .then(response => response.json())
      .then(data => {
        alert('上传成功:' + data.url);
      })
      .catch(err => {
        console.error('上传失败:', err);
      });
    }

关键技术对比表

技术环节 传统方案 HTML5方案
文件读取 依赖后台接收原始文件 FileReader前端预处理
图像处理 服务器端ImageMagick等工具 Canvas客户端实时压缩
格式转换 后台转码耗时 前端toBlob指定输出格式
进度反馈 页面刷新后显示 onUploadProgress实时进度条
兼容性处理 IE需Flash插件 现代浏览器原生支持

问题与解答

Q1:如何动态调整压缩比例?
A1:在toBlob方法中修改第二个参数(0-1数值),数值越小压缩率越高,可通过滑动条实时调整:

<input type="range" min="0.1" max="1" step="0.1" id="quality">
const quality = document.getElementById('quality').value;
canvas.toBlob(callback, type, parseFloat(quality));

Q2:如何处理超过2GB的大文件?
A2:采用分片上传策略:

  1. 使用slice方法分割文件:file.slice(start, end)
  2. 逐片压缩并上传
  3. 合并分片(需服务器支持)
    示例代码:

    const chunkSize = 5  1024  1024; // 5MB每片
    let currentChunk = 0;
    while(currentChunk < file.size) {
    const chunk = file.slice(currentChunk, currentChunk+chunkSize);
    // 压缩并上传该片段...
    currentChunk += chunkSize;
0