我正在使用 ckeditor5 库,当我复制图像时,它会使用 Base64UploadAdapter 插件转换为 Base64。如果图像很大,我想以编程方式将其调整为预定义的大小。
https://github.com/ckeditor/ckeditor5/issues/5657给出了解决方案,但它使用了一个库(browser-image-compression),我不想使用它
能够解决问题:
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;
}
}