压缩图片及文件base64和File格式互转

项目中有用到上传图片、压缩图片、图片格式转化等功能,现将封装的方法整理如下:

input file 转为 base64 格式

  /**
   * File 转为 base64
   */
  public fileToBase64(file: File) {
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    return new Promise(resolve => {
      fileReader.onload = () => {
        resolve(fileReader.result);
      };
    });
  }

base64 格式转为 File 格式

  /**
   * base64 转为 File 格式
   */
  public async base64ToFile(dataUrl: string, file: File): Promise {
    const res: Response = await fetch(dataUrl);
    const blob: Blob = await res.blob();
    const result = new File([blob], file.name, { type: file.type });
    return result;
  }

将存于 url 链接中的文件转为 Blob 格式

  /**
   * 将url格式的文件转换为blob格式
   * @param httpUrl: 后台给的文件地址
   */
  public async urlToBlob(httpUrl) {
    const res: Response = await fetch(httpUrl);
    const blob: Blob = await res.blob();
    const blobUrl = URL.createObjectURL(blob);
    return blobUrl;
  }

将 url 文件下载保存至本地

  /**
   * 保存文件到本地
   */
  public downloadToLocal(blobUrl, name) {
    // 创建虚拟a标签
    const eleLink = document.createElement('a');
    eleLink.download = name;
    eleLink.style.display = 'none';
    eleLink.href = blobUrl;
    // 触发点击
    document.body.appendChild(eleLink);
    eleLink.click();
    // 然后移除
    document.body.removeChild(eleLink);
    URL.revokeObjectURL(blobUrl);
  }

压缩图片

  /**
   * 压缩图片
   */
  public async compressedImg(file: File, maxW = 1080, quality = 0.6): Promise {
    // 将file文件转为base格式
    const result: any = await this.fileToBase64(file);

    // 新建一个img标签(不嵌入DOM节点,仅做canvas操作)
    const image = new Image();
    // 让该标签加载base64格式的原图
    image.src = result;
    // 图片加载完毕后再通过canvas压缩图片,图片还没加载完就压缩,结果图片是全黑的
    return new Promise(resolve => {
      image.onload = () => {
        // 最大尺寸限制
        const maxWidth = maxW;
        // maxHeight = maxH;

        // 图片原始尺寸
        const originWidth = image.width,
          originHeight = image.height;

        // 目标尺寸
        let targetWidth = originWidth,
          targetHeight = originHeight;

        // 图片尺寸超过限制时
        if (originWidth > maxWidth) {
          // 更宽,按照宽度限定尺寸
          targetWidth = maxWidth;
          targetHeight = Math.round(maxWidth * (originHeight / originWidth));
          // if (originWidth / originHeight > maxWidth / maxHeight) {
          //   // 更宽,按照宽度限定尺寸
          //   targetWidth = maxWidth;
          //   targetHeight = Math.round(maxWidth * (originHeight / originWidth));
          // } else {
          //   targetHeight = maxHeight;
          //   targetWidth = Math.round(maxHeight * (originWidth / originHeight));
          // }
        } else {
          targetWidth = originWidth;
          targetHeight = originHeight;
        }

        // 创建一个canvas元素
        const canvas = document.createElement('canvas');
        // context相当于画笔,里面有各种可以进行绘图的API
        const context = canvas.getContext('2d');
        // 压缩后图片的宽度,例如 imageWidth = image.width / 2;

        let imgData = ''; // 存储压缩后的图片
        canvas.width = targetWidth; // 设置绘图的宽度
        canvas.height = targetHeight; // 设置绘图的高度
        // 使用drawImage重新设置img标签中的图片大小,实现压缩和图片裁剪
        context.drawImage(image, 0, 0, targetWidth, targetHeight);
        // 使用toDataURL将canvas上的图片转换为base64格式, 有损压缩为原来的0.6,默认值为0.92,最小为0.1
        imgData = canvas.toDataURL(file.type, quality);
        resolve(imgData);
      };
    });

  }

你可能感兴趣的:(压缩图片及文件base64和File格式互转)