使用canvas压缩jpeg与webp

23 阅读2分钟

FileReader

  FileReader 对象 允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。

readAsDataURL

  readAsDataURL 方法 会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成 DONE,并触发 loadend 事件,同时 result 属性将包含一个 data:URL 格式的字符串(base64 编码)以表示所读取文件的内容。

示例:

function previewFile() {
  var preview = document.querySelector("img");
  var file = document.querySelector("input[type=file]").files[0];
  var reader = new FileReader();

  reader.addEventListener(
    "load",
    function () {
      preview.src = reader.result;
    },
    false
  );

  if (file) {
    reader.readAsDataURL(file);
  }
}

canvas

  Canvas 提供了一个通过 JavaScript 和 HTML 的<canvas>元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。

drawImage

  Canvas 2D API 中的 CanvasRenderingContext2D.drawImage() 方法提供了多种在画布(Canvas)上绘制图像的方式。

drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

toDataURL

  HTMLCanvasElement.toDataURL() 方法返回一个包含图片展示的 data URI。可以使用 type 参数指定其类型,默认为 PNG 格式。图片的分辨率为 96dpi。

参数:

  • type 可选
    • 图片格式,默认为 image/png
  • encoderOptions 可选
    • 在指定图片格式为 image/jpeg 或 image/webp 的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。

完整代码

interface Options {
  file: File;
  quality?: number;
  success?: (base64: string) => void;
}

/**
 * 适用于jpeg、webp
 */
class CompressImage {
  options: Options;
  fileReader = new FileReader();
  constructor(options: Options) {
    this.options = options;
    this.createBase64();
  }

  createBase64() {
    this.fileReader.readAsDataURL(this.options.file);
    this.fileReader.onload = (e) => {
      this.compress(e.target.result as string);
    };
  }

  compress(base64: string) {
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    const img = new Image();
    img.src = base64;
    img.onload = () => {
      canvas.width = img.width;
      canvas.height = img.height;
      ctx.drawImage(img, 0, 0, img.width, img.height);
      const newBase64 = canvas.toDataURL(
        this.options.file.type,
        this.options.quality
      );
      this.options.success(newBase64);
    };
  }
}

const file = document.querySelector("#file") as HTMLInputElement;

file.addEventListener("change", (e) => {
  const target = e.target as HTMLInputElement;
  const fileObject = target.files[0];
  if (fileObject) {
    new CompressImage({
      file: fileObject,
      quality: 0.6,
      success: (base64) => {
        document.body.innerHTML = `<img src='${base64}' />`;
      },
    });
  }
});

对应源代码链接