Ckeditor 5:大图像副本应在转换为 Base64 之前调整图像大小

问题描述 投票:0回答:1

我正在使用 ckeditor5 库,当我复制图像时,它会使用 Base64UploadAdapter 插件转换为 Base64。如果图像很大,我想以编程方式将其调整为预定义的大小。

https://github.com/ckeditor/ckeditor5/issues/5657给出了解决方案,但它使用了一个库(browser-image-compression),我不想使用它

base64 ckeditor5
1个回答
0
投票

能够解决问题:

Base64UploadAdapter 的副本:

import ImageResize from './image-resize';

export default class Base64UploadAdapter extends Plugin {
    :
    :
}

class Adapter implements UploadAdapter {
    :
    :
    private imageResize: ImageResize;
    :
    :
    public upload(): Promise<UploadResponse> {
        return new Promise( ( resolve, reject ) => {
            :
            :
            reader.addEventListener('load', async () => {
                const base64Image = await this.imageResize.readerOnloadCustomization(reader.result as string, { width: 300, height: 300 });
                resolve({ default: base64Image });
            });
            :
            :
        });
    }
    :
    :
}

image-resize.ts

export interface ImageSizeConfig {
  width: number;
  height: number;
}

export default class ImageResize {
  private canvasElem: HTMLCanvasElement | null = null;
  private imgObj: HTMLImageElement | null = null;

  async readerOnloadCustomization(imgBase64Data: string, maxImgSize: ImageSizeConfig): Promise<string> {
    try {
      this.canvasElem = document.createElement('canvas');
      this.imgObj = new Image();

      if (this.canvasElem && this.imgObj) {
        this.canvasElem.id = 'Canvas';
        this.imgObj.src = imgBase64Data;

        await new Promise((resolve, reject) => {
          this.imgObj!.onload = resolve;
          this.imgObj!.onerror = reject;
        });

        const imgSize = { width: this.imgObj.width, height: this.imgObj.height };
        const scaledImgSize = await this.scaleImageSize(imgSize, maxImgSize);
        imgBase64Data = await this.resizeImage(this.canvasElem, this.imgObj, imgSize, scaledImgSize);

        // Clear objects after processing
        this.clearObjects();
        return imgBase64Data;
      }
    } catch (error) {
      // Clear objects after processing
      this.clearObjects();
      throw error;
    }
    // Clear objects after processing
    this.clearObjects();
    return imgBase64Data;
  }

  scaleImageSize(imageSize: ImageSizeConfig, maxImgSize: ImageSizeConfig): Promise<ImageSizeConfig> {
    return new Promise((resolve) => {
      let calculatedWidth = imageSize.width;
      let calculatedHeight = imageSize.height;
      if (calculatedWidth > maxImgSize.width) {
        const h2wRatio = parseFloat((imageSize.height / imageSize.width).toPrecision(4));
        calculatedWidth = maxImgSize.width;
        calculatedHeight = Math.round(calculatedWidth * h2wRatio);
      }
      if (calculatedHeight > maxImgSize.height) {
        const w2hRatio = parseFloat((calculatedWidth / calculatedHeight).toPrecision(4));
        calculatedHeight = maxImgSize.height;
        calculatedWidth = Math.round(calculatedHeight * w2hRatio);
      }
      resolve({
        width: calculatedWidth,
        height: calculatedHeight
      });
    });
  }

  resizeImage(
    canvas: HTMLCanvasElement,
    img: HTMLImageElement,
    originalImgSize: ImageSizeConfig,
    calculatedImgSize: ImageSizeConfig
  ): Promise<string> {
    return new Promise((resolve) => {
      let ctx = canvas.getContext('2d');
      canvas.width = calculatedImgSize.width;
      canvas.height = calculatedImgSize.height;
      if (ctx)
        ctx.drawImage(img, 0, 0, originalImgSize.width, originalImgSize.height, 0, 0, canvas.width, canvas.height);
      resolve(canvas.toDataURL());
    });
  }

  private clearObjects(): void {
    // Set objects to null
    this.canvasElem = null;
    this.imgObj = null;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.