原生js压缩图片及大小调整

8,491 阅读1分钟

上传和下载图像是web应用中的一个是十分常见的交互功能,随着移动设备上摄像头的分辨率不断提高。上传图片是一件高资源消耗的任务,有时候一张手机图片会大于10M,所以作为开发人员,我们应该在上传到服务器之前就将图片进行一次压缩,今天给大家带来的压缩方法是纯js实现,并非用第三方压缩工具

上传图片

  • 使用input上传图片
// 上传图片
 <input id="img-input" type="file" accept="image/*" style="display:block" />
  • 获取上传图片文件
// 获取上传图片文件
 const input = document.getElementById(‘input’);
   input.onChange = function(ev) {
   const file = ev.target.files[0];
   };
  • 创建URL
// 前端指北 js压缩图片及调整大小
const blobURL = window.URL.createObjectURL(file)
  • 创建img对象并赋值url
// 前端指北 js压缩图片及调整大小
const img = new Image()
img.src = blobURL
  • 使用onload来处理图像
// 前端指北 js压缩图片及调整大小
img.onload = function (ev) {
  window.URL.revokeObjectURL(blobURL) 
}
  • 创建一个canvas元素,将图片的宽高设置为画布的宽高
// 前端指北 js压缩图片及调整大小
const canvas = document.createElement(‘canvas’);
canvas.width = newWidth;
canvas.height = newHeight;
  • 在画布上绘制图像
// 前端指北 js压缩图片及调整大小
const ctx = canvas.getContext(‘2d’);
ctx.drawImage(img, 0, 0, newWidth, newHeight);
  • 输出自定义质量图像
// 前端指北 js压缩图片及调整大小
canvas.toBlob(
  function (blob) {
    // Handle the compressed image
  },
  mimeType,
  quality
)

mimeType 是图像的类型,如 image/jpeg、 image/png。quality值范围从0到1,表示输出图像的质量。

最终代码


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root">
      <p>上传一张图片试试</p>
      <input
        id="img-input"
        type="file"
        accept="image/*"
        style="display: block"
      />
    </div>
    <script>
      const MAX_WIDTH = 320;
      const MAX_HEIGHT = 180;
      const MIME_TYPE = 'image/jpeg';
      const QUALITY = 0.7;

      const input = document.getElementById('img-input');
      input.onchange = function (ev) {
        const file = ev.target.files[0]
        const blobURL = URL.createObjectURL(file);
        const img = new Image();
        img.src = blobURL;
        img.onerror = function () {
          URL.revokeObjectURL(this.src);
          console.log('无法加载图像');
        };
        img.onload = function () {
          URL.revokeObjectURL(this.src);
          const [newWidth, newHeight] = calculateSize(
            img,
            MAX_WIDTH,
            MAX_HEIGHT
          );
          const canvas = document.createElement('canvas');
          canvas.width = newWidth;
          canvas.height = newHeight;
          const ctx = canvas.getContext('2d');
          ctx.drawImage(img, 0, 0, newWidth, newHeight);
          canvas.toBlob(
            (blob) => {
              displayInfo('原文件大小', file);
              displayInfo('压缩后', blob);
            },
            MIME_TYPE,
            QUALITY
          );
          document.getElementById('root').append(canvas);
        };
      };

      function calculateSize(img, maxWidth, maxHeight) {
        let width = img.width;
        let height = img.height;

        // calculate the width and height, constraining the proportions
        if (width > height) {
          if (width > maxWidth) {
            height = Math.round((height * maxWidth) / width);
            width = maxWidth;
          }
        } else {
          if (height > maxHeight) {
            width = Math.round((width * maxHeight) / height);
            height = maxHeight;
          }
        }
        return [width, height];
      }


      function displayInfo(label, file) {
        const p = document.createElement('p');
        p.innerText = `${label} - ${readableBytes(file.size)}`;
        document.getElementById('root').append(p);
      }

      function readableBytes(bytes) {
        const i = Math.floor(Math.log(bytes) / Math.log(1024)),
          sizes = ['B''KB''MB''GB''TB''PB''EB''ZB''YB'];

        return (bytes / Math.pow(1024, i)).toFixed(2) + ' ' + sizes[i];
      }
    </script>
  </body>
</html>

图片