From 8d2bc9b84f711978ddbab60de57148c0ebcf98c5 Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Thu, 30 Oct 2025 18:14:41 +0900
Subject: [PATCH] wip
---
locales/index.d.ts | 6 +-
locales/ja-JP.yml | 3 +-
.../components/MkImageLabelEditorDialog.vue | 5 ++
.../src/utility/image-label-renderer.ts | 55 ++++++++++---------
4 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 8871a67178..4d8c86b110 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -5611,9 +5611,13 @@ export interface Locale extends ILocale {
*/
"title": string;
/**
- * フレーム
+ * フレームの幅
*/
"frameThickness": string;
+ /**
+ * ラベルの幅
+ */
+ "labelThickness": string;
/**
* 中央揃え
*/
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 5d4e5f7a6f..d6a1dff2b6 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1399,7 +1399,8 @@ deviceInfoDescription: "技術的なお問い合わせの際に、以下の情
_imageLabelEditor:
title: "ラベルの編集"
- frameThickness: "フレーム"
+ frameThickness: "フレームの幅"
+ labelThickness: "ラベルの幅"
centered: "中央揃え"
captionMain: "キャプション(大)"
captionSub: "キャプション(小)"
diff --git a/packages/frontend/src/components/MkImageLabelEditorDialog.vue b/packages/frontend/src/components/MkImageLabelEditorDialog.vue
index e48321766a..81e1438d86 100644
--- a/packages/frontend/src/components/MkImageLabelEditorDialog.vue
+++ b/packages/frontend/src/components/MkImageLabelEditorDialog.vue
@@ -34,6 +34,10 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._imageLabelEditor.frameThickness }}
+
+ {{ i18n.ts._imageLabelEditor.labelThickness }}
+
+
{{ i18n.ts._imageLabelEditor.centered }}
@@ -109,6 +113,7 @@ const props = defineProps<{
const frame = reactive(deepClone(props.frame) ?? {
style: 'frame',
frameThickness: 0.05,
+ labelThickness: 0.2,
title: 'Untitled by @syuilo',
text: '{mm}mm f/{f} {s}s ISO{iso}',
centered: false,
diff --git a/packages/frontend/src/utility/image-label-renderer.ts b/packages/frontend/src/utility/image-label-renderer.ts
index b7a25f22f3..fc6627f56b 100644
--- a/packages/frontend/src/utility/image-label-renderer.ts
+++ b/packages/frontend/src/utility/image-label-renderer.ts
@@ -18,6 +18,7 @@ const FXS = [
export type ImageLabelParams = {
style: 'frame' | 'frameLess';
frameThickness: number;
+ labelThickness: number;
title: string;
text: string;
centered: boolean;
@@ -26,11 +27,9 @@ export type ImageLabelParams = {
export class ImageLabelRenderer {
private effector: ImageEffector;
- private renderWidth: number;
- private renderHeight: number;
private image: HTMLImageElement | ImageBitmap;
- private paddingBottom = 0;
private exif: ExifReader.Tags;
+ private renderAsPreview = false;
constructor(options: {
canvas: HTMLCanvasElement,
@@ -40,30 +39,13 @@ export class ImageLabelRenderer {
}) {
this.image = options.image;
this.exif = options.exif;
+ this.renderAsPreview = options.renderAsPreview ?? false;
console.log(this.exif);
- let w = this.image.width;
- let h = this.image.height;
-
- if (options.renderAsPreview) {
- const MAX_W = 1000;
- const MAX_H = 1000;
-
- if (w > MAX_W || h > MAX_H) {
- const scale = Math.min(MAX_W / w, MAX_H / h);
- w = Math.floor(w * scale);
- h = Math.floor(h * scale);
- }
- }
-
- this.paddingBottom = Math.floor(h * 0.2);
- this.renderWidth = w;
- this.renderHeight = h + this.paddingBottom;
-
this.effector = new ImageEffector({
canvas: options.canvas,
- renderWidth: this.renderWidth,
- renderHeight: this.renderHeight,
+ renderWidth: 1,
+ renderHeight: 1,
image: null,
fxs: FXS,
});
@@ -89,10 +71,28 @@ export class ImageLabelRenderer {
}
public async update(params: ImageLabelParams): Promise {
- const aspectRatio = this.renderWidth / this.renderHeight;
+ let w = this.image.width;
+ let h = this.image.height;
+
+ if (this.renderAsPreview) {
+ const MAX_W = 1000;
+ const MAX_H = 1000;
+
+ if (w > MAX_W || h > MAX_H) {
+ const scale = Math.min(MAX_W / w, MAX_H / h);
+ w = Math.floor(w * scale);
+ h = Math.floor(h * scale);
+ }
+ }
+
+ const paddingBottom = Math.floor(h * params.labelThickness);
+ const renderWidth = w;
+ const renderHeight = h + paddingBottom;
+
+ const aspectRatio = renderWidth / renderHeight;
const ctx = window.document.createElement('canvas').getContext('2d')!;
- ctx.canvas.width = this.renderWidth;
- ctx.canvas.height = this.paddingBottom;
+ ctx.canvas.width = renderWidth;
+ ctx.canvas.height = paddingBottom;
const fontSize = ctx.canvas.height / 6;
const marginX = Math.max(fontSize * 2, (ctx.canvas.width * params.frameThickness) / aspectRatio);
const withQrCode = params.withQrCode;
@@ -184,6 +184,8 @@ export class ImageLabelRenderer {
await this.effector.registerTexture('label', data);
+ this.effector.changeResolution(renderWidth, renderHeight);
+
await this.effector.setLayers([{
fxId: 'label',
id: 'a',
@@ -194,7 +196,6 @@ export class ImageLabelRenderer {
imageMarginY: paddingY,
},
}]);
- this.render();
}
public render(): void {