1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-07-13 00:10:37 +02:00

Desktop: Added more methods to the imaging plugin API

This commit is contained in:
Laurent Cozic
2023-09-17 14:08:55 +01:00
parent 3d8c96489f
commit 3b4717b674
47 changed files with 1091 additions and 26 deletions

View File

@ -1,5 +1,10 @@
/* eslint-disable multiline-comment-style */
import Resource from '../../../models/Resource';
import Setting from '../../../models/Setting';
import shim from '../../../shim';
import { Rectangle } from './types';
export interface Implementation {
nativeImage: any;
}
@ -63,21 +68,61 @@ export default class JoplinImaging {
return handle;
}
/**
* Create an image from a buffer - however only use this for very small
* images. It requires transferring the full image data from the plugin to
* the app, which is extremely slow and will freeze the app. Instead, use
* `createFromPath` or `createFromResource`, which will manipulate the image
* data directly from the main process.
*/
public async createFromBuffer(buffer: any, options: CreateFromBufferOptions = null): Promise<Handle> {
return this.cacheImage(this.implementation_.nativeImage.createFromBuffer(buffer, options));
}
public async createFromPath(filePath: string): Promise<Handle> {
return this.cacheImage(this.implementation_.nativeImage.createFromPath(filePath));
}
public async createFromResource(resourceId: string): Promise<Handle> {
const resource = await Resource.load(resourceId);
if (!resource) throw new Error(`No such resource: ${resourceId}`);
const resourcePath = await Resource.fullPath(resource);
if (!(await shim.fsDriver().exists(resourcePath))) throw new Error(`Could not load resource path: ${resourcePath}`);
return this.createFromPath(resourcePath);
}
public async getSize(handle: Handle) {
const image = this.imageByHandle(handle);
return image.data.getSize();
}
public async resize(handle: Handle, options: ResizeOptions = null) {
const image = this.imageByHandle(handle);
const resizedImage = image.data.resize(options);
return this.cacheImage(resizedImage);
}
public async crop(handle: Handle, rectange: Rectangle) {
const image = this.imageByHandle(handle);
const croppedImage = image.data.crop(rectange);
return this.cacheImage(croppedImage);
}
/**
* Warnings: requires transferring the complete image from the app to the
* plugin which may freeze the app. Consider using one of the `toXxxFile()`
* or `toXxxResource()` methods instead.
*/
public async toDataUrl(handle: Handle): Promise<string> {
const image = this.imageByHandle(handle);
return image.data.toDataURL();
}
/**
* Warnings: requires transferring the complete image from the app to the
* plugin which may freeze the app. Consider using one of the `toXxxFile()`
* or `toXxxResource()` methods instead.
*/
public async toBase64(handle: Handle) {
const dataUrl = await this.toDataUrl(handle);
const s = dataUrl.split('base64,');
@ -85,6 +130,49 @@ export default class JoplinImaging {
return s[1];
}
public async toPngFile(handle: Handle, filePath: string) {
const image = this.imageByHandle(handle);
const data = image.data.toPNG();
await shim.fsDriver().writeFile(filePath, data, 'buffer');
}
/**
* Quality is between 0 and 100
*/
public async toJpgFile(handle: Handle, filePath: string, quality = 80) {
const image = this.imageByHandle(handle);
const data = image.data.toJPEG(quality);
await shim.fsDriver().writeFile(filePath, data, 'buffer');
}
private tempFilePath(ext: string) {
return `${Setting.value('tempDir')}/${Date.now()}_${Math.random()}.${ext}`;
}
/**
* Creates a new Joplin resource from the image data. The image will be
* first converted to a JPEG.
*/
public async toJpgResource(handle: Handle, resourceProps: any, quality = 80) {
const tempFilePath = this.tempFilePath('jpg');
await this.toJpgFile(handle, tempFilePath, quality);
const newResource = await shim.createResourceFromPath(tempFilePath, resourceProps, { resizeLargeImages: 'never' });
await shim.fsDriver().remove(tempFilePath);
return newResource;
}
/**
* Creates a new Joplin resource from the image data. The image will be
* first converted to a PNG.
*/
public async toPngResource(handle: Handle, resourceProps: any) {
const tempFilePath = this.tempFilePath('png');
await this.toPngFile(handle, tempFilePath);
const newResource = await shim.createResourceFromPath(tempFilePath, resourceProps, { resizeLargeImages: 'never' });
await shim.fsDriver().remove(tempFilePath);
return newResource;
}
/**
* Image data is not automatically deleted by Joplin so make sure you call
* this method on the handle once you are done.

View File

@ -359,6 +359,13 @@ export interface DialogResult {
formData?: any;
}
export interface Rectangle {
x?: number;
y?: number;
width?: number;
height?: number;
}
// =================================================================
// Settings types
// =================================================================