前端图片上传时使用canvas进行图片压缩

使用场景:后端无需做图片大小验证,前端直接进行图片压缩,传给后端base64格式的图片地址。话不多说直接上代码:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>cavans图片压缩</title>
  </head>
  <body>
    <input type="file" id="upload" multiple />
    <script>
      // 文件规则
      const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg'];
      const MAXSIZE = 6 * 1024 * 1024;
      const MAXSIZE_STR = '1MB';

      const upload = document.querySelector('#upload');
      // 监听文件上传事件并传值
      upload.addEventListener('change', (e) => {
        console.log(e.target.files);
        const [file] = e.target.files;
        if (!file) {
          return;
        }
        const { type: fileType, size: fileSize } = file;
        // 图片类型检查
        if (!ACCEPT.includes(fileType)) {
          alert(`暂时不支持${fileType}文件类型`);
          upload.value = '';
          return;
        }
        // 图片大小检查
        if (fileSize > MAXSIZE) {
          alert(`该文件超出${MAXSIZE_STR}`);
          upload.value = '';
          return;
        }
        converImageToBase64(file, (base64Image) =>
          compress(base64Image, uploadToServer)
        );
      });

      // 原图转为base64
      function converImageToBase64(file, callback) {
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.addEventListener('load', function (e) {
          const base64Image = e.target.result;
          // console.log('原图base64', base64Image);
          // 将nase64文件传入压缩方法中
          callback && callback(base64Image);
        });
      }
      // 图片压缩主要代码
      function compress(base64Image, callback) {
        let maxW = 1024;
        let maxH = 1024;
        const image = new Image();
        image.src = base64Image;
        // document.body.appendChild(image); 

        // 监听图片加载事件
        image.addEventListener('load', function (e) {
          let ratio; // 图片压缩比
          let needCompress = false; // 图片是否需要压缩
          if (maxW < image.naturalWidth) {
            needCompress = true;
            ratio = image.naturalWidth / maxW;
            maxH = image.naturalHeight / ratio;
          }
          if (!needCompress) {
            ratio = image.naturalHeight / maxH;
            maxW = image.naturalHeight / ratio;
          }
          const canvas = document.createElement('canvas');
          canvas.setAttribute('id', '__compress__');
          canvas.width = maxW;
          canvas.height = maxH;
          canvas.style.visibility = 'hidden';
          document.body.appendChild(canvas);

          const ctx = canvas.getContext('2d');
          ctx.clearRect(0, 0, maxW, maxH);
          ctx.drawImage(image, 0, 0, maxW, maxH);
          const compressImage = canvas.toDataURL('image/jpeg', 0.8); // 值越大压缩后的图片越小,但是太小图片会失真
          callback && callback(compressImage);
          // 显示压缩后的图片
          const _image = new Image();
          _image.src = compressImage;
          document.body.appendChild(_image); // 预览压缩后的图片
          canvas.remove();
          // console.log('压缩比', image.src.length / _image.src.length);
        });
      }
      // 压缩后的base64上传到服务器
      function uploadToServer(compressImage) {
        console.log('uploadToServer......', compressImage);
        if (compressImage) {
          alert('图片压缩成功');
        }
      }
    </script>
  </body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值