generated from tpl/obsidian-sample-plugin
			Add in-browser image compression
This commit is contained in:
		
							parent
							
								
									05daa707d8
								
							
						
					
					
						commit
						2ba8523a24
					
				
							
								
								
									
										26
									
								
								src/main.ts
								
								
								
								
							
							
						
						
									
										26
									
								
								src/main.ts
								
								
								
								
							| 
						 | 
					@ -33,6 +33,7 @@ import { ReloadReadingLogCommand } from "@commands/ReloadReadingLogCommand";
 | 
				
			||||||
import { registerReadingCalendarCodeBlockProcessor } from "@ui/code-blocks/ReadingCalendarCodeBlock";
 | 
					import { registerReadingCalendarCodeBlockProcessor } from "@ui/code-blocks/ReadingCalendarCodeBlock";
 | 
				
			||||||
import { registerAToZChallengeCodeBlockProcessor } from "@ui/code-blocks/AToZChallengeCodeBlock";
 | 
					import { registerAToZChallengeCodeBlockProcessor } from "@ui/code-blocks/AToZChallengeCodeBlock";
 | 
				
			||||||
import moment from "@external/moment";
 | 
					import moment from "@external/moment";
 | 
				
			||||||
 | 
					import { compressImage } from "@utils/image";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class BookTrackerPlugin extends Plugin {
 | 
					export default class BookTrackerPlugin extends Plugin {
 | 
				
			||||||
	public settings: BookTrackerPluginSettings;
 | 
						public settings: BookTrackerPluginSettings;
 | 
				
			||||||
| 
						 | 
					@ -127,25 +128,30 @@ export default class BookTrackerPlugin extends Plugin {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		filePath += fileName + "." + extension;
 | 
							filePath += fileName + "." + extension;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const existingFile = this.app.vault.getFileByPath(filePath);
 | 
							let file = this.app.vault.getFileByPath(filePath);
 | 
				
			||||||
		if (existingFile) {
 | 
							if (file) {
 | 
				
			||||||
			if (this.settings.overwriteExistingCovers || overwrite) {
 | 
								if (this.settings.overwriteExistingCovers || overwrite) {
 | 
				
			||||||
				await this.app.vault.modifyBinary(
 | 
									await this.app.vault.modifyBinary(file, response.arrayBuffer);
 | 
				
			||||||
					existingFile,
 | 
					 | 
				
			||||||
					response.arrayBuffer
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				new Notice("Cover image already exists: " + filePath);
 | 
									new Notice("Cover image already exists: " + filePath);
 | 
				
			||||||
 | 
									return file;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return existingFile;
 | 
							} else {
 | 
				
			||||||
		}
 | 
								file = await this.app.vault.createBinary(
 | 
				
			||||||
 | 
					 | 
				
			||||||
		return await this.app.vault.createBinary(
 | 
					 | 
				
			||||||
				filePath,
 | 
									filePath,
 | 
				
			||||||
				response.arrayBuffer
 | 
									response.arrayBuffer
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							await compressImage(this.app, file, {
 | 
				
			||||||
 | 
								height: 400,
 | 
				
			||||||
 | 
								quality: 0.8,
 | 
				
			||||||
 | 
								maintainAspectRatio: true,
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return file;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	async createEntry(book: Book): Promise<void> {
 | 
						async createEntry(book: Book): Promise<void> {
 | 
				
			||||||
		const fileName = this.templater
 | 
							const fileName = this.templater
 | 
				
			||||||
			.renderTemplate(this.settings.fileNameFormat, {
 | 
								.renderTemplate(this.settings.fileNameFormat, {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,72 @@
 | 
				
			||||||
 | 
					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<HTMLImageElement>((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<Blob>((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());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue