import { type App, type TFile } from "obsidian"; interface CompressOptions { width?: number; height?: number; maintainAspectRatio?: boolean; quality?: number; } export async function compressImage( app: App, file: TFile, options: CompressOptions ) { const img = await new Promise((resolve) => { const img = new Image(); img.src = app.vault.getResourcePath(file); img.onload = () => { resolve(img); }; }); const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d")!; const quality = options.quality ?? 1; let height = options.height; let width = options.width; if (!width && !height) { width = img.width; height = img.height; } else if (!width && height) { width = height * (img.width / img.height); } else if (!height && width) { height = width * (img.height / img.width); } if (options.maintainAspectRatio) { const aspectRatio = img.width / img.height; if (options.height) if (width! > height!) { height = width! / aspectRatio; } else { width = height! * aspectRatio; } } console.log(width, height); canvas.width = width!; canvas.height = height!; ctx.drawImage(img, 0, 0, width!, height!); const blob = await new Promise((resolve, reject) => { canvas.toBlob( (blob) => { if (blob) { resolve(blob); } else { reject(new Error("Failed to compress image")); } }, "image/jpeg", quality ); }); return app.vault.modifyBinary(file, await blob.arrayBuffer()); }