mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-14 18:27:44 +02:00
This commit is contained in:
parent
af7cbcbca7
commit
8aad67ccfe
@ -2,7 +2,7 @@ import ResourceEditWatcher from '@joplin/lib/services/ResourceEditWatcher/index'
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { copyHtmlToClipboard } from './clipboardUtils';
|
||||
import bridge from '../../../services/bridge';
|
||||
import { ContextMenuItemType, ContextMenuOptions, ContextMenuItems, resourceInfo, textToDataUri, svgUriToPng } from './contextMenuUtils';
|
||||
import { ContextMenuItemType, ContextMenuOptions, ContextMenuItems, resourceInfo, textToDataUri, svgUriToPng, svgDimensions } from './contextMenuUtils';
|
||||
const Menu = bridge().Menu;
|
||||
const MenuItem = bridge().MenuItem;
|
||||
import Resource from '@joplin/lib/models/Resource';
|
||||
@ -106,8 +106,10 @@ export function menuItems(dispatch: Function): ContextMenuItems {
|
||||
if (!options.filename) {
|
||||
throw new Error('Filename is needed to save as png');
|
||||
}
|
||||
// double dimensions to make sure it's always big enough even on hdpi screens
|
||||
const [width, height] = svgDimensions(document, options.textToCopy).map((x: number) => x * 2 || undefined);
|
||||
const dataUri = textToDataUri(options.textToCopy, options.mime);
|
||||
const png = await svgUriToPng(document, dataUri);
|
||||
const png = await svgUriToPng(document, dataUri, width, height);
|
||||
const filename = options.filename.replace('.svg', '.png');
|
||||
await saveFileData(png, filename);
|
||||
},
|
||||
|
@ -1,5 +1,6 @@
|
||||
import Resource from '@joplin/lib/models/Resource';
|
||||
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
const logger = Logger.create('contextMenuUtils');
|
||||
export enum ContextMenuItemType {
|
||||
None = '',
|
||||
Image = 'image',
|
||||
@ -40,8 +41,23 @@ export async function resourceInfo(options: ContextMenuOptions) {
|
||||
export function textToDataUri(text: string, mime: string): string {
|
||||
return `data:${mime};base64,${Buffer.from(text).toString('base64')}`;
|
||||
}
|
||||
|
||||
export const svgUriToPng = (document: Document, svg: string) => {
|
||||
export const svgDimensions = (document: Document, svg: string) => {
|
||||
let width: number;
|
||||
let height: number;
|
||||
try {
|
||||
const parser = new DOMParser();
|
||||
const id = parser.parseFromString(svg, 'text/html').querySelector('svg').id;
|
||||
({ width, height } = document.querySelector<HTMLIFrameElement>('.noteTextViewer').contentWindow.document.querySelector(`#${id}`).getBoundingClientRect());
|
||||
} catch (error) {
|
||||
logger.warn('Could not get SVG dimensions.');
|
||||
logger.warn('Error was: ', error);
|
||||
}
|
||||
if (!width || !height) {
|
||||
return [undefined, undefined];
|
||||
}
|
||||
return [width, height];
|
||||
};
|
||||
export const svgUriToPng = (document: Document, svg: string, width: number, height: number) => {
|
||||
return new Promise<Uint8Array>((resolve, reject) => {
|
||||
let canvas: HTMLCanvasElement;
|
||||
let img: HTMLImageElement;
|
||||
@ -63,11 +79,21 @@ export const svgUriToPng = (document: Document, svg: string) => {
|
||||
try {
|
||||
canvas = document.createElement('canvas');
|
||||
if (!canvas) throw new Error('Failed to create canvas element');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
if (!width || !height) {
|
||||
const maxDimension = 1024;
|
||||
if (img.width > img.height) {
|
||||
width = maxDimension;
|
||||
height = width * (img.height / img.width);
|
||||
} else {
|
||||
height = maxDimension;
|
||||
width = height * (img.width / img.height);
|
||||
}
|
||||
}
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) throw new Error('Failed to get context');
|
||||
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width, img.height);
|
||||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height);
|
||||
const pngUri = canvas.toDataURL('image/png');
|
||||
if (!pngUri) throw new Error('Failed to generate png uri');
|
||||
const pngBase64 = pngUri.split(',')[1];
|
||||
|
Loading…
Reference in New Issue
Block a user