diff options
Diffstat (limited to 'packages/frontend/src/utility/watermark.ts')
| -rw-r--r-- | packages/frontend/src/utility/watermark.ts | 218 |
1 files changed, 0 insertions, 218 deletions
diff --git a/packages/frontend/src/utility/watermark.ts b/packages/frontend/src/utility/watermark.ts deleted file mode 100644 index 1b46721a2b..0000000000 --- a/packages/frontend/src/utility/watermark.ts +++ /dev/null @@ -1,218 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import type { ImageEffectorFx, ImageEffectorLayer } from '@/utility/image-effector/ImageEffector.js'; -import { FX_watermarkPlacement } from '@/utility/image-effector/fxs/watermarkPlacement.js'; -import { FX_stripe } from '@/utility/image-effector/fxs/stripe.js'; -import { FX_polkadot } from '@/utility/image-effector/fxs/polkadot.js'; -import { FX_checker } from '@/utility/image-effector/fxs/checker.js'; -import { ImageEffector } from '@/utility/image-effector/ImageEffector.js'; - -const WATERMARK_FXS = [ - FX_watermarkPlacement, - FX_stripe, - FX_polkadot, - FX_checker, -] as const satisfies ImageEffectorFx<string, any>[]; - -type Align = { x: 'left' | 'center' | 'right'; y: 'top' | 'center' | 'bottom'; margin?: number; }; - -export type WatermarkPreset = { - id: string; - name: string; - layers: ({ - id: string; - type: 'text'; - text: string; - repeat: boolean; - noBoundingBoxExpansion: boolean; - scale: number; - angle: number; - align: Align; - opacity: number; - } | { - id: string; - type: 'image'; - imageUrl: string | null; - imageId: string | null; - cover: boolean; - repeat: boolean; - noBoundingBoxExpansion: boolean; - scale: number; - angle: number; - align: Align; - opacity: number; - } | { - id: string; - type: 'qr'; - data: string; - scale: number; - align: Align; - opacity: number; - } | { - id: string; - type: 'stripe'; - angle: number; - frequency: number; - threshold: number; - color: [r: number, g: number, b: number]; - opacity: number; - } | { - id: string; - type: 'polkadot'; - angle: number; - scale: number; - majorRadius: number; - majorOpacity: number; - minorDivisions: number; - minorRadius: number; - minorOpacity: number; - color: [r: number, g: number, b: number]; - opacity: number; - } | { - id: string; - type: 'checker'; - angle: number; - scale: number; - color: [r: number, g: number, b: number]; - opacity: number; - })[]; -}; - -export class WatermarkRenderer { - private effector: ImageEffector<typeof WATERMARK_FXS>; - private layers: WatermarkPreset['layers'] = []; - - constructor(options: { - canvas: HTMLCanvasElement, - renderWidth: number, - renderHeight: number, - image: HTMLImageElement | ImageBitmap, - }) { - this.effector = new ImageEffector({ - canvas: options.canvas, - renderWidth: options.renderWidth, - renderHeight: options.renderHeight, - image: options.image, - fxs: WATERMARK_FXS, - }); - } - - private makeImageEffectorLayers(): ImageEffectorLayer[] { - return this.layers.map(layer => { - if (layer.type === 'text') { - return { - fxId: 'watermarkPlacement', - id: layer.id, - params: { - repeat: layer.repeat, - noBoundingBoxExpansion: layer.noBoundingBoxExpansion, - scale: layer.scale, - align: layer.align, - angle: layer.angle, - opacity: layer.opacity, - cover: false, - watermark: { - type: 'text', - text: layer.text, - }, - }, - }; - } else if (layer.type === 'image') { - return { - fxId: 'watermarkPlacement', - id: layer.id, - params: { - repeat: layer.repeat, - noBoundingBoxExpansion: layer.noBoundingBoxExpansion, - scale: layer.scale, - align: layer.align, - angle: layer.angle, - opacity: layer.opacity, - cover: layer.cover, - watermark: { - type: 'url', - url: layer.imageUrl, - }, - }, - }; - } else if (layer.type === 'qr') { - return { - fxId: 'watermarkPlacement', - id: layer.id, - params: { - repeat: false, - scale: layer.scale, - align: layer.align, - angle: 0, - opacity: layer.opacity, - cover: false, - watermark: { - type: 'qr', - data: layer.data, - }, - }, - }; - } else if (layer.type === 'stripe') { - return { - fxId: 'stripe', - id: layer.id, - params: { - angle: layer.angle, - frequency: layer.frequency, - threshold: layer.threshold, - color: layer.color, - opacity: layer.opacity, - }, - }; - } else if (layer.type === 'polkadot') { - return { - fxId: 'polkadot', - id: layer.id, - params: { - angle: layer.angle, - scale: layer.scale, - majorRadius: layer.majorRadius, - majorOpacity: layer.majorOpacity, - minorDivisions: layer.minorDivisions, - minorRadius: layer.minorRadius, - minorOpacity: layer.minorOpacity, - color: layer.color, - }, - }; - } else if (layer.type === 'checker') { - return { - fxId: 'checker', - id: layer.id, - params: { - angle: layer.angle, - scale: layer.scale, - color: layer.color, - opacity: layer.opacity, - }, - }; - } else { - throw new Error(`Unrecognized layer type: ${(layer as any).type}`); - } - }); - } - - public async setLayers(layers: WatermarkPreset['layers']) { - this.layers = layers; - await this.effector.setLayers(this.makeImageEffectorLayers()); - this.render(); - } - - public render(): void { - this.effector.render(); - } - - /* - * disposeCanvas = true だとloseContextを呼ぶため、コンストラクタで渡されたcanvasも再利用不可になるので注意 - */ - public destroy(disposeCanvas = true): void { - this.effector.destroy(disposeCanvas); - } -} |