@enslo/sd-metadata 1.8.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +114 -92
- package/README.md +114 -92
- package/dist/index.d.ts +154 -120
- package/dist/index.js +2797 -2824
- package/dist/index.js.map +1 -1
- package/package.json +11 -8
package/README.ja.md
CHANGED
|
@@ -29,17 +29,22 @@ npm install @enslo/sd-metadata
|
|
|
29
29
|
| ------ | :---: | :----: | :----: |
|
|
30
30
|
| [NovelAI](https://novelai.net/) * | ✅ | 🔄️ | ✅ |
|
|
31
31
|
| [ComfyUI](https://github.com/comfyanonymous/ComfyUI) * | ✅ | 🔄️ | 🔄️ |
|
|
32
|
-
| [
|
|
33
|
-
| [Forge](https://github.com/lllyasviel/stable-diffusion-webui-forge)
|
|
32
|
+
| [Stable Diffusion WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) | ✅ | ✅ | ✅ |
|
|
33
|
+
| [Forge](https://github.com/lllyasviel/stable-diffusion-webui-forge) | ✅ | ✅ | ✅ |
|
|
34
|
+
| [Forge Classic](https://github.com/Haoming02/sd-webui-forge-classic/tree/classic) | ✅ | ✅ | ✅ |
|
|
35
|
+
| [Forge Neo](https://github.com/Haoming02/sd-webui-forge-classic/tree/neo) | ✅ | ✅ | ✅ |
|
|
36
|
+
| [reForge](https://github.com/Panchovix/stable-diffusion-webui-reForge) | ✅ | ✅ | ✅ |
|
|
37
|
+
| [EasyReforge](https://github.com/Zuntan03/EasyReforge) | ✅ | ✅ | ✅ |
|
|
38
|
+
| [SD.Next](https://github.com/vladmandic/automatic) | ✅ | ✅ | ✅ |
|
|
34
39
|
| [InvokeAI](https://github.com/invoke-ai/InvokeAI) | ✅ | 🔄️ | 🔄️ |
|
|
35
|
-
| [SwarmUI](https://github.com/
|
|
40
|
+
| [SwarmUI](https://github.com/mcmonkeyprojects/SwarmUI) * | ✅ | ✅ | ✅ |
|
|
36
41
|
| [Civitai](https://civitai.com/) | ⚠️ | ✅ | ⚠️ |
|
|
37
42
|
| [TensorArt](https://tensor.art/) | ✅ | 🔄️ | 🔄️ |
|
|
38
43
|
| [Stability Matrix](https://github.com/LykosAI/StabilityMatrix) | ✅ | 🔄️ | 🔄️ |
|
|
39
44
|
| [HuggingFace Space](https://huggingface.co/spaces) | ✅ | 🔄️ | 🔄️ |
|
|
45
|
+
| [Fooocus](https://github.com/lllyasviel/Fooocus) | ⚠️ | ⚠️ | ⚠️ |
|
|
40
46
|
| [Ruined Fooocus](https://github.com/runew0lf/RuinedFooocus) | ✅ | 🔄️ | 🔄️ |
|
|
41
47
|
| [Easy Diffusion](https://github.com/easydiffusion/easydiffusion) | ⚠️ | ⚠️ | ⚠️ |
|
|
42
|
-
| [Fooocus](https://github.com/lllyasviel/Fooocus) | ⚠️ | ⚠️ | ⚠️ |
|
|
43
48
|
|
|
44
49
|
**凡例:**
|
|
45
50
|
|
|
@@ -149,7 +154,7 @@ if (result.status === 'success') {
|
|
|
149
154
|
> 本番環境では `@latest` の代わりに特定のバージョンを指定してください:
|
|
150
155
|
>
|
|
151
156
|
> ```text
|
|
152
|
-
> https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@
|
|
157
|
+
> https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@2.0.0/dist/index.js
|
|
153
158
|
> ```
|
|
154
159
|
|
|
155
160
|
### 応用例
|
|
@@ -264,16 +269,14 @@ if (result.ok) {
|
|
|
264
269
|
</details>
|
|
265
270
|
|
|
266
271
|
<details>
|
|
267
|
-
<summary
|
|
272
|
+
<summary>カスタムメタデータの埋め込み</summary>
|
|
268
273
|
|
|
269
|
-
|
|
274
|
+
A1111フォーマットでカスタムメタデータを作成して埋め込み:
|
|
270
275
|
|
|
271
276
|
```typescript
|
|
272
|
-
import {
|
|
277
|
+
import { embed } from '@enslo/sd-metadata';
|
|
273
278
|
|
|
274
|
-
// カスタムメタデータをゼロから作成
|
|
275
279
|
const metadata = {
|
|
276
|
-
software: 'sd-webui',
|
|
277
280
|
prompt: 'masterpiece, best quality, 1girl',
|
|
278
281
|
negativePrompt: 'lowres, bad quality',
|
|
279
282
|
width: 512,
|
|
@@ -288,45 +291,64 @@ const metadata = {
|
|
|
288
291
|
};
|
|
289
292
|
|
|
290
293
|
// 任意の画像フォーマット(PNG、JPEG、WebP)に書き込み
|
|
291
|
-
const result =
|
|
294
|
+
const result = embed(imageData, metadata);
|
|
292
295
|
if (result.ok) {
|
|
293
296
|
writeFileSync('output.png', result.value);
|
|
294
297
|
}
|
|
295
298
|
```
|
|
296
299
|
|
|
300
|
+
`extras` で設定行に任意のキーバリューを追加できます:
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
const result = embed(imageData, {
|
|
304
|
+
...metadata,
|
|
305
|
+
extras: {
|
|
306
|
+
Version: 'v1.10.0',
|
|
307
|
+
'Lora hashes': 'abc123',
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
```
|
|
311
|
+
|
|
297
312
|
> [!TIP]
|
|
298
|
-
>
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
313
|
+
> extras のキーが構造化フィールド(例:`Steps`)と一致する場合、extras の値が元の位置で構造化フィールドを上書きします。新しいキーは末尾に追加されます。
|
|
314
|
+
|
|
315
|
+
`EmbedMetadata` はすべての `GenerationMetadata` バリアントのサブセットなので、パース結果のメタデータをそのまま渡せます — `characterPrompts` を持つ NovelAI も含めて:
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
import { read, embed } from '@enslo/sd-metadata';
|
|
319
|
+
|
|
320
|
+
const result = read(novelaiPng);
|
|
321
|
+
if (result.status === 'success') {
|
|
322
|
+
// NovelAI(や他のツール)のメタデータをそのまま利用可能
|
|
323
|
+
const output = embed(blankJpeg, result.metadata);
|
|
324
|
+
}
|
|
325
|
+
```
|
|
303
326
|
|
|
304
327
|
</details>
|
|
305
328
|
|
|
306
329
|
<details>
|
|
307
330
|
<summary>表示用にメタデータをフォーマット</summary>
|
|
308
331
|
|
|
309
|
-
|
|
332
|
+
`ParseResult` を読みやすい文字列に変換します。ステータスに応じて最適な表現を自動選択します:
|
|
310
333
|
|
|
311
334
|
```typescript
|
|
312
|
-
import { read,
|
|
335
|
+
import { read, stringify } from '@enslo/sd-metadata';
|
|
313
336
|
|
|
314
337
|
const result = read(imageData);
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
const text = formatAsWebUI(result.metadata);
|
|
338
|
+
const text = stringify(result);
|
|
339
|
+
if (text) {
|
|
318
340
|
console.log(text);
|
|
319
|
-
|
|
320
|
-
//
|
|
341
|
+
|
|
342
|
+
// 'success' の場合: WebUIフォーマットで出力:
|
|
321
343
|
// masterpiece, best quality, 1girl
|
|
322
344
|
// Negative prompt: lowres, bad quality
|
|
323
345
|
// Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, Size: 512x768, Model: model.safetensors
|
|
346
|
+
//
|
|
347
|
+
// 'unrecognized' の場合: 生のメタデータテキストを出力
|
|
348
|
+
// 'empty' / 'invalid' の場合: 空文字列を返す
|
|
324
349
|
}
|
|
325
350
|
```
|
|
326
351
|
|
|
327
|
-
> [!NOTE]
|
|
328
|
-
> どのツールで生成された画像であっても、`formatAsWebUI` は共通の生成パラメータを抽出し、標準化された形式に整形します。ツール固有のフォーマットを意識することなく、ユーザーにメタデータを表示するのに最適です。
|
|
329
|
-
|
|
330
352
|
</details>
|
|
331
353
|
|
|
332
354
|
## APIリファレンス
|
|
@@ -366,16 +388,14 @@ if (result.status === 'success') {
|
|
|
366
388
|
- `'conversionFailed'`: メタデータ変換に失敗(例:互換性のないフォーマット)
|
|
367
389
|
- `'writeFailed'`: 画像へのメタデータ埋め込みに失敗
|
|
368
390
|
|
|
369
|
-
### `
|
|
391
|
+
### `embed(input: Uint8Array | ArrayBuffer, metadata: EmbedMetadata | GenerationMetadata): WriteResult`
|
|
370
392
|
|
|
371
|
-
SD WebUI (A1111)
|
|
393
|
+
SD WebUI (A1111) フォーマットでカスタムメタデータを画像に埋め込みます。
|
|
372
394
|
|
|
373
395
|
**パラメータ:**
|
|
374
396
|
|
|
375
397
|
- `input` - ターゲット画像ファイルデータ(PNG、JPEG、またはWebP)
|
|
376
|
-
- `metadata` -
|
|
377
|
-
- 任意のツールからでも、カスタム作成でも可能
|
|
378
|
-
- 自動的にWebUIフォーマットに変換される
|
|
398
|
+
- `metadata` - 埋め込む `EmbedMetadata` または `GenerationMetadata`(`extras` で任意のキーバリューを追加可能)
|
|
379
399
|
|
|
380
400
|
**戻り値:**
|
|
381
401
|
|
|
@@ -390,65 +410,37 @@ SD WebUI (A1111) フォーマットで画像にメタデータを書き込みま
|
|
|
390
410
|
- 他のツールからWebUI互換フォーマットにメタデータを変換
|
|
391
411
|
- WebUIで読み取り可能なメタデータを出力するアプリケーションの構築
|
|
392
412
|
|
|
393
|
-
### `
|
|
413
|
+
### `stringify(input: ParseResult | EmbedMetadata | GenerationMetadata): string`
|
|
394
414
|
|
|
395
|
-
|
|
415
|
+
メタデータを読みやすい文字列に変換します。`ParseResult`、`EmbedMetadata`、`GenerationMetadata` のいずれも受け付けます。
|
|
396
416
|
|
|
397
417
|
**パラメータ:**
|
|
398
418
|
|
|
399
|
-
- `
|
|
419
|
+
- `input` - `ParseResult`、`EmbedMetadata`、または `GenerationMetadata`
|
|
400
420
|
|
|
401
421
|
**戻り値:**
|
|
402
422
|
|
|
403
|
-
- WebUI
|
|
404
|
-
|
|
405
|
-
**出力フォーマット:**
|
|
406
|
-
|
|
407
|
-
```text
|
|
408
|
-
positive prompt
|
|
409
|
-
[NovelAIのキャラクタープロンプト]
|
|
410
|
-
Negative prompt: negative prompt
|
|
411
|
-
Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, Size: 512x768, ...
|
|
412
|
-
```
|
|
423
|
+
- `ParseResult` の場合: `success` → WebUIフォーマット、`unrecognized` → 生テキスト、`empty`/`invalid` → 空文字列
|
|
424
|
+
- `EmbedMetadata` / `GenerationMetadata` の場合: WebUIフォーマットのテキスト
|
|
413
425
|
|
|
414
426
|
**ユースケース:**
|
|
415
427
|
|
|
416
|
-
-
|
|
417
|
-
-
|
|
418
|
-
-
|
|
419
|
-
|
|
420
|
-
### `formatRaw(raw: RawMetadata): string`
|
|
421
|
-
|
|
422
|
-
生のメタデータをプレーンテキストとしてフォーマットします。
|
|
423
|
-
|
|
424
|
-
**パラメータ:**
|
|
425
|
-
|
|
426
|
-
- `raw` - `ParseResult` から得られた生のメタデータ(`result.raw`)
|
|
427
|
-
|
|
428
|
-
**戻り値:**
|
|
428
|
+
- 画像ビューアやギャラリーでの生成パラメータ表示
|
|
429
|
+
- メタデータをクリップボードに読みやすいテキストとしてコピー
|
|
430
|
+
- パース結果のログ出力やデバッグ
|
|
431
|
+
- `EmbedMetadata` の事前プレビュー(埋め込み前の確認用)
|
|
429
432
|
|
|
430
|
-
|
|
433
|
+
### `softwareLabels: Record<GenerationSoftware, string>`
|
|
431
434
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
- 認識できないメタデータをユーザーに表示
|
|
435
|
-
- 生のメタデータ内容の素早い確認
|
|
436
|
-
- パース失敗時のフォールバック表示
|
|
437
|
-
|
|
438
|
-
**例:**
|
|
435
|
+
`GenerationSoftware` の識別子から表示用の名前への読み取り専用マッピング。
|
|
439
436
|
|
|
440
437
|
```typescript
|
|
441
|
-
import {
|
|
438
|
+
import { softwareLabels } from '@enslo/sd-metadata';
|
|
442
439
|
|
|
443
440
|
const result = read(imageData);
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
console.log(formatAsWebUI(result.metadata));
|
|
448
|
-
break;
|
|
449
|
-
case 'unrecognized':
|
|
450
|
-
console.log(formatRaw(result.raw));
|
|
451
|
-
break;
|
|
441
|
+
if (result.status === 'success') {
|
|
442
|
+
console.log(softwareLabels[result.metadata.software]);
|
|
443
|
+
// => "NovelAI", "ComfyUI", "Stable Diffusion WebUI", etc.
|
|
452
444
|
}
|
|
453
445
|
```
|
|
454
446
|
|
|
@@ -468,22 +460,26 @@ type ParseResult =
|
|
|
468
460
|
| { status: 'invalid'; message?: string };
|
|
469
461
|
```
|
|
470
462
|
|
|
471
|
-
### `
|
|
463
|
+
### `BaseMetadata`
|
|
472
464
|
|
|
473
|
-
`
|
|
465
|
+
全メタデータ型で共有される共通フィールド。このインターフェースは `EmbedMetadata` の基盤でもあります。
|
|
474
466
|
|
|
475
|
-
|
|
467
|
+
```typescript
|
|
468
|
+
interface BaseMetadata {
|
|
469
|
+
prompt: string;
|
|
470
|
+
negativePrompt: string;
|
|
471
|
+
width: number;
|
|
472
|
+
height: number;
|
|
473
|
+
model?: ModelSettings;
|
|
474
|
+
sampling?: SamplingSettings;
|
|
475
|
+
hires?: HiresSettings;
|
|
476
|
+
upscale?: UpscaleSettings;
|
|
477
|
+
}
|
|
478
|
+
```
|
|
476
479
|
|
|
477
|
-
|
|
480
|
+
### `GenerationMetadata`
|
|
478
481
|
|
|
479
|
-
|
|
480
|
-
- `negativePrompt: string` - ネガティブプロンプトテキスト
|
|
481
|
-
- `width: number` - 画像の幅(ピクセル)
|
|
482
|
-
- `height: number` - 画像の高さ(ピクセル)
|
|
483
|
-
- `model?: ModelSettings` - モデル情報(name、hash、VAE)
|
|
484
|
-
- `sampling?: SamplingSettings` - サンプリングパラメータ(seed、steps、CFG、sampler、scheduler、clipSkip)
|
|
485
|
-
- `hires?: HiresSettings` - Hires.fix設定(適用されている場合)
|
|
486
|
-
- `upscale?: UpscaleSettings` - アップスケール設定(適用されている場合)
|
|
482
|
+
`read()` 関数が返す統一されたメタデータ構造。`software` フィールドで区別される3つのメタデータ型のユニオン型です。全タイプが `BaseMetadata` を拡張しています。
|
|
487
483
|
|
|
488
484
|
**メタデータ型のバリアント:**
|
|
489
485
|
|
|
@@ -498,7 +494,7 @@ type ParseResult =
|
|
|
498
494
|
- `nodes: ComfyNodeGraph`(comfyui/tensorart/stability-matrixでは必須)
|
|
499
495
|
- `nodes?: ComfyNodeGraph`(swarmuiではオプション - PNGフォーマットのみ)
|
|
500
496
|
|
|
501
|
-
- **`StandardMetadata`** (`software: 'sd-webui' | 'forge' | '
|
|
497
|
+
- **`StandardMetadata`** (`software: 'sd-webui' | 'forge' | 'forge-classic' | 'reforge' | 'invokeai' | ...`)
|
|
502
498
|
ツール固有の拡張なしのベースラインメタデータ。ほとんどのSD WebUIベースのツールで使用。
|
|
503
499
|
|
|
504
500
|
**型定義:**
|
|
@@ -545,6 +541,29 @@ if (result.status === 'success') {
|
|
|
545
541
|
|
|
546
542
|
各メタデータ型の詳細なインターフェース定義については[型ドキュメント](./docs/types.ja.md)を参照してください。
|
|
547
543
|
|
|
544
|
+
### `GenerationSoftware`
|
|
545
|
+
|
|
546
|
+
サポートされている全ソフトウェア識別子の文字列リテラルユニオン型。`softwareLabels` のキー型として使用します。
|
|
547
|
+
|
|
548
|
+
```typescript
|
|
549
|
+
type GenerationSoftware =
|
|
550
|
+
| 'novelai' | 'comfyui' | 'swarmui' | 'tensorart' | 'stability-matrix'
|
|
551
|
+
| 'sd-webui' | 'forge' | 'forge-classic' | 'forge-neo'
|
|
552
|
+
| 'reforge'| 'easy-reforge' | 'sd-next' | 'civitai' | 'hf-space'
|
|
553
|
+
| 'invokeai' | 'easydiffusion' | 'fooocus' | 'ruined-fooocus';
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### `EmbedMetadata`
|
|
557
|
+
|
|
558
|
+
`embed()` と `stringify()` で使用するユーザー作成カスタムメタデータ型。`GenerationMetadata` が既知のAIツールからのパース結果を表すのに対し、`EmbedMetadata` はユーザーが独自にメタデータを組み立てるための型です。`BaseMetadata` にオプションのキャラクタープロンプトと設定行への任意キーバリュー(`extras`)を追加。
|
|
559
|
+
|
|
560
|
+
```typescript
|
|
561
|
+
type EmbedMetadata = BaseMetadata &
|
|
562
|
+
Pick<NovelAIMetadata, 'characterPrompts'> & {
|
|
563
|
+
extras?: Record<string, string | number>;
|
|
564
|
+
};
|
|
565
|
+
```
|
|
566
|
+
|
|
548
567
|
### `RawMetadata`
|
|
549
568
|
|
|
550
569
|
ラウンドトリップ変換のために元のメタデータ構造を保持します。
|
|
@@ -560,11 +579,14 @@ type RawMetadata =
|
|
|
560
579
|
> TypeScriptユーザー向け:全ての型はエクスポートされており、インポートして使用できます。
|
|
561
580
|
>
|
|
562
581
|
> ```typescript
|
|
563
|
-
> import type {
|
|
564
|
-
>
|
|
565
|
-
>
|
|
566
|
-
>
|
|
567
|
-
>
|
|
582
|
+
> import type {
|
|
583
|
+
> BaseMetadata,
|
|
584
|
+
> EmbedMetadata,
|
|
585
|
+
> ParseResult,
|
|
586
|
+
> GenerationMetadata,
|
|
587
|
+
> GenerationSoftware,
|
|
588
|
+
> ModelSettings,
|
|
589
|
+
> SamplingSettings
|
|
568
590
|
> } from '@enslo/sd-metadata';
|
|
569
591
|
> ```
|
|
570
592
|
>
|
package/README.md
CHANGED
|
@@ -29,17 +29,22 @@ npm install @enslo/sd-metadata
|
|
|
29
29
|
| ------ | :---: | :----: | :----: |
|
|
30
30
|
| [NovelAI](https://novelai.net/) * | ✅ | 🔄️ | ✅ |
|
|
31
31
|
| [ComfyUI](https://github.com/comfyanonymous/ComfyUI) * | ✅ | 🔄️ | 🔄️ |
|
|
32
|
-
| [
|
|
33
|
-
| [Forge](https://github.com/lllyasviel/stable-diffusion-webui-forge)
|
|
32
|
+
| [Stable Diffusion WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) | ✅ | ✅ | ✅ |
|
|
33
|
+
| [Forge](https://github.com/lllyasviel/stable-diffusion-webui-forge) | ✅ | ✅ | ✅ |
|
|
34
|
+
| [Forge Classic](https://github.com/Haoming02/sd-webui-forge-classic/tree/classic) | ✅ | ✅ | ✅ |
|
|
35
|
+
| [Forge Neo](https://github.com/Haoming02/sd-webui-forge-classic/tree/neo) | ✅ | ✅ | ✅ |
|
|
36
|
+
| [reForge](https://github.com/Panchovix/stable-diffusion-webui-reForge) | ✅ | ✅ | ✅ |
|
|
37
|
+
| [EasyReforge](https://github.com/Zuntan03/EasyReforge) | ✅ | ✅ | ✅ |
|
|
38
|
+
| [SD.Next](https://github.com/vladmandic/automatic) | ✅ | ✅ | ✅ |
|
|
34
39
|
| [InvokeAI](https://github.com/invoke-ai/InvokeAI) | ✅ | 🔄️ | 🔄️ |
|
|
35
|
-
| [SwarmUI](https://github.com/
|
|
40
|
+
| [SwarmUI](https://github.com/mcmonkeyprojects/SwarmUI) * | ✅ | ✅ | ✅ |
|
|
36
41
|
| [Civitai](https://civitai.com/) | ⚠️ | ✅ | ⚠️ |
|
|
37
42
|
| [TensorArt](https://tensor.art/) | ✅ | 🔄️ | 🔄️ |
|
|
38
43
|
| [Stability Matrix](https://github.com/LykosAI/StabilityMatrix) | ✅ | 🔄️ | 🔄️ |
|
|
39
44
|
| [HuggingFace Space](https://huggingface.co/spaces) | ✅ | 🔄️ | 🔄️ |
|
|
45
|
+
| [Fooocus](https://github.com/lllyasviel/Fooocus) | ⚠️ | ⚠️ | ⚠️ |
|
|
40
46
|
| [Ruined Fooocus](https://github.com/runew0lf/RuinedFooocus) | ✅ | 🔄️ | 🔄️ |
|
|
41
47
|
| [Easy Diffusion](https://github.com/easydiffusion/easydiffusion) | ⚠️ | ⚠️ | ⚠️ |
|
|
42
|
-
| [Fooocus](https://github.com/lllyasviel/Fooocus) | ⚠️ | ⚠️ | ⚠️ |
|
|
43
48
|
|
|
44
49
|
**Legend:**
|
|
45
50
|
|
|
@@ -148,7 +153,7 @@ if (result.status === 'success') {
|
|
|
148
153
|
> For production use, pin to a specific version instead of `@latest`:
|
|
149
154
|
>
|
|
150
155
|
> ```text
|
|
151
|
-
> https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@
|
|
156
|
+
> https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@2.0.0/dist/index.js
|
|
152
157
|
> ```
|
|
153
158
|
|
|
154
159
|
### Advanced Examples
|
|
@@ -263,16 +268,14 @@ if (result.ok) {
|
|
|
263
268
|
</details>
|
|
264
269
|
|
|
265
270
|
<details>
|
|
266
|
-
<summary>
|
|
271
|
+
<summary>Embedding Custom Metadata</summary>
|
|
267
272
|
|
|
268
|
-
Create and embed custom metadata in
|
|
273
|
+
Create and embed custom metadata in A1111 format:
|
|
269
274
|
|
|
270
275
|
```typescript
|
|
271
|
-
import {
|
|
276
|
+
import { embed } from '@enslo/sd-metadata';
|
|
272
277
|
|
|
273
|
-
// Create custom metadata from scratch
|
|
274
278
|
const metadata = {
|
|
275
|
-
software: 'sd-webui',
|
|
276
279
|
prompt: 'masterpiece, best quality, 1girl',
|
|
277
280
|
negativePrompt: 'lowres, bad quality',
|
|
278
281
|
width: 512,
|
|
@@ -287,45 +290,61 @@ const metadata = {
|
|
|
287
290
|
};
|
|
288
291
|
|
|
289
292
|
// Write to any image format (PNG, JPEG, WebP)
|
|
290
|
-
const result =
|
|
293
|
+
const result = embed(imageData, metadata);
|
|
291
294
|
if (result.ok) {
|
|
292
295
|
writeFileSync('output.png', result.value);
|
|
293
296
|
}
|
|
294
297
|
```
|
|
295
298
|
|
|
299
|
+
You can also add arbitrary key-value pairs to the settings line with `extras`:
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
const result = embed(imageData, {
|
|
303
|
+
...metadata,
|
|
304
|
+
extras: { Version: 'v1.10.0', 'Lora hashes': 'abc123' },
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+
|
|
296
308
|
> [!TIP]
|
|
297
|
-
> `
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
309
|
+
> If an extras key matches a structured field (e.g., `Steps`), the extras value overrides the structured value at its original position. New keys are appended at the end.
|
|
310
|
+
|
|
311
|
+
Since `EmbedMetadata` is a subset of all `GenerationMetadata` variants, you can pass parsed metadata directly — including NovelAI with its `characterPrompts`:
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
import { read, embed } from '@enslo/sd-metadata';
|
|
315
|
+
|
|
316
|
+
const result = read(novelaiPng);
|
|
317
|
+
if (result.status === 'success') {
|
|
318
|
+
// NovelAI metadata (or any other tool) works as-is
|
|
319
|
+
const output = embed(blankJpeg, result.metadata);
|
|
320
|
+
}
|
|
321
|
+
```
|
|
302
322
|
|
|
303
323
|
</details>
|
|
304
324
|
|
|
305
325
|
<details>
|
|
306
326
|
<summary>Formatting Metadata for Display</summary>
|
|
307
327
|
|
|
308
|
-
Convert
|
|
328
|
+
Convert a `ParseResult` to a human-readable string. Automatically selects the best representation based on status:
|
|
309
329
|
|
|
310
330
|
```typescript
|
|
311
|
-
import { read,
|
|
331
|
+
import { read, stringify } from '@enslo/sd-metadata';
|
|
312
332
|
|
|
313
333
|
const result = read(imageData);
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
const text = formatAsWebUI(result.metadata);
|
|
334
|
+
const text = stringify(result);
|
|
335
|
+
if (text) {
|
|
317
336
|
console.log(text);
|
|
318
|
-
|
|
319
|
-
//
|
|
337
|
+
|
|
338
|
+
// For 'success': outputs in WebUI format:
|
|
320
339
|
// masterpiece, best quality, 1girl
|
|
321
340
|
// Negative prompt: lowres, bad quality
|
|
322
341
|
// Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, Size: 512x768, Model: model.safetensors
|
|
342
|
+
//
|
|
343
|
+
// For 'unrecognized': outputs raw metadata text
|
|
344
|
+
// For 'empty' / 'invalid': returns empty string
|
|
323
345
|
}
|
|
324
346
|
```
|
|
325
347
|
|
|
326
|
-
> [!NOTE]
|
|
327
|
-
> Regardless of which tool generated the image, `formatAsWebUI` extracts the common generation parameters and formats them in a standardized way. This is ideal for displaying metadata to users without worrying about tool-specific formats.
|
|
328
|
-
|
|
329
348
|
</details>
|
|
330
349
|
|
|
331
350
|
## API Reference
|
|
@@ -365,16 +384,14 @@ Writes metadata to an image file.
|
|
|
365
384
|
- `'conversionFailed'`: Metadata conversion failed (e.g., incompatible format)
|
|
366
385
|
- `'writeFailed'`: Failed to embed metadata into the image
|
|
367
386
|
|
|
368
|
-
### `
|
|
387
|
+
### `embed(input: Uint8Array | ArrayBuffer, metadata: EmbedMetadata | GenerationMetadata): WriteResult`
|
|
369
388
|
|
|
370
|
-
|
|
389
|
+
Embeds custom metadata into an image in SD WebUI (A1111) format.
|
|
371
390
|
|
|
372
391
|
**Parameters:**
|
|
373
392
|
|
|
374
393
|
- `input` - Target image file data (PNG, JPEG, or WebP)
|
|
375
|
-
- `metadata` -
|
|
376
|
-
- Can be from any tool or custom-created
|
|
377
|
-
- Automatically converted to WebUI format
|
|
394
|
+
- `metadata` - `EmbedMetadata` or `GenerationMetadata` to embed (use `extras` field for custom settings)
|
|
378
395
|
|
|
379
396
|
**Returns:**
|
|
380
397
|
|
|
@@ -389,65 +406,40 @@ Writes metadata to an image in SD WebUI (A1111) format.
|
|
|
389
406
|
- Converting metadata from other tools to WebUI-compatible format
|
|
390
407
|
- Building applications that output WebUI-readable metadata
|
|
391
408
|
|
|
392
|
-
### `
|
|
409
|
+
### `stringify(input: ParseResult | EmbedMetadata | GenerationMetadata): string`
|
|
393
410
|
|
|
394
|
-
|
|
411
|
+
Converts metadata to a human-readable string.
|
|
395
412
|
|
|
396
413
|
**Parameters:**
|
|
397
414
|
|
|
398
|
-
- `
|
|
415
|
+
- `input` - One of:
|
|
416
|
+
- `ParseResult` from `read()` — selects best representation based on status
|
|
417
|
+
- `EmbedMetadata` or `GenerationMetadata` — formats as A1111 text directly
|
|
399
418
|
|
|
400
419
|
**Returns:**
|
|
401
420
|
|
|
402
|
-
- Human-readable
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
```text
|
|
407
|
-
positive prompt
|
|
408
|
-
[character prompts for NovelAI]
|
|
409
|
-
Negative prompt: negative prompt
|
|
410
|
-
Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, Size: 512x768, ...
|
|
411
|
-
```
|
|
421
|
+
- `ParseResult` with `success` → Human-readable text in WebUI format
|
|
422
|
+
- `ParseResult` with `unrecognized` → Raw metadata as plain text
|
|
423
|
+
- `ParseResult` with `empty` / `invalid` → Empty string
|
|
424
|
+
- `EmbedMetadata` / `GenerationMetadata` → Human-readable text in WebUI format
|
|
412
425
|
|
|
413
426
|
**Use cases:**
|
|
414
427
|
|
|
415
|
-
- Displaying
|
|
416
|
-
- Copying
|
|
417
|
-
- Logging or debugging
|
|
428
|
+
- Displaying generation parameters in image viewers or galleries
|
|
429
|
+
- Copying metadata to clipboard as readable text
|
|
430
|
+
- Logging or debugging parsed metadata
|
|
418
431
|
|
|
419
|
-
### `
|
|
432
|
+
### `softwareLabels: Record<GenerationSoftware, string>`
|
|
420
433
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
**Parameters:**
|
|
424
|
-
|
|
425
|
-
- `raw` - Raw metadata from `ParseResult` (`result.raw`)
|
|
426
|
-
|
|
427
|
-
**Returns:**
|
|
428
|
-
|
|
429
|
-
- Plain text content from the metadata (multiple entries separated by blank lines)
|
|
430
|
-
|
|
431
|
-
**Use cases:**
|
|
432
|
-
|
|
433
|
-
- Displaying unrecognized metadata to users
|
|
434
|
-
- Quick inspection of raw metadata content
|
|
435
|
-
- Fallback display when parsing fails
|
|
436
|
-
|
|
437
|
-
**Example:**
|
|
434
|
+
A read-only mapping from `GenerationSoftware` identifiers to their human-readable display names.
|
|
438
435
|
|
|
439
436
|
```typescript
|
|
440
|
-
import {
|
|
437
|
+
import { softwareLabels } from '@enslo/sd-metadata';
|
|
441
438
|
|
|
442
439
|
const result = read(imageData);
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
console.log(formatAsWebUI(result.metadata));
|
|
447
|
-
break;
|
|
448
|
-
case 'unrecognized':
|
|
449
|
-
console.log(formatRaw(result.raw));
|
|
450
|
-
break;
|
|
440
|
+
if (result.status === 'success') {
|
|
441
|
+
console.log(softwareLabels[result.metadata.software]);
|
|
442
|
+
// => "NovelAI", "ComfyUI", "Stable Diffusion WebUI", etc.
|
|
451
443
|
}
|
|
452
444
|
```
|
|
453
445
|
|
|
@@ -467,22 +459,26 @@ type ParseResult =
|
|
|
467
459
|
| { status: 'invalid'; message?: string };
|
|
468
460
|
```
|
|
469
461
|
|
|
470
|
-
### `
|
|
462
|
+
### `BaseMetadata`
|
|
471
463
|
|
|
472
|
-
|
|
464
|
+
Common fields shared by all metadata types. This interface is also the foundation of `EmbedMetadata`.
|
|
473
465
|
|
|
474
|
-
|
|
466
|
+
```typescript
|
|
467
|
+
interface BaseMetadata {
|
|
468
|
+
prompt: string;
|
|
469
|
+
negativePrompt: string;
|
|
470
|
+
width: number;
|
|
471
|
+
height: number;
|
|
472
|
+
model?: ModelSettings;
|
|
473
|
+
sampling?: SamplingSettings;
|
|
474
|
+
hires?: HiresSettings;
|
|
475
|
+
upscale?: UpscaleSettings;
|
|
476
|
+
}
|
|
477
|
+
```
|
|
475
478
|
|
|
476
|
-
|
|
479
|
+
### `GenerationMetadata`
|
|
477
480
|
|
|
478
|
-
|
|
479
|
-
- `negativePrompt: string` - Negative prompt text
|
|
480
|
-
- `width: number` - Image width in pixels
|
|
481
|
-
- `height: number` - Image height in pixels
|
|
482
|
-
- `model?: ModelSettings` - Model information (name, hash, VAE)
|
|
483
|
-
- `sampling?: SamplingSettings` - Sampling parameters (seed, steps, CFG, sampler, scheduler, clipSkip)
|
|
484
|
-
- `hires?: HiresSettings` - Hires.fix settings (if applied)
|
|
485
|
-
- `upscale?: UpscaleSettings` - Upscale settings (if applied)
|
|
481
|
+
Unified metadata structure returned by the `read()` function. This is a discriminated union of 3 specific metadata types, distinguished by the `software` field. All types extend `BaseMetadata`.
|
|
486
482
|
|
|
487
483
|
**Metadata Type Variants:**
|
|
488
484
|
|
|
@@ -497,7 +493,7 @@ All metadata types include these base fields:
|
|
|
497
493
|
- `nodes: ComfyNodeGraph` (required for comfyui/tensorart/stability-matrix)
|
|
498
494
|
- `nodes?: ComfyNodeGraph` (optional for swarmui - only in PNG format)
|
|
499
495
|
|
|
500
|
-
- **`StandardMetadata`** (`software: 'sd-webui' | 'forge' | '
|
|
496
|
+
- **`StandardMetadata`** (`software: 'sd-webui' | 'forge' | 'forge-classic' | 'reforge' | 'invokeai' | ...`)
|
|
501
497
|
Baseline metadata without tool-specific extensions. Used by most SD WebUI-based tools.
|
|
502
498
|
|
|
503
499
|
**Type Definition:**
|
|
@@ -544,6 +540,29 @@ if (result.status === 'success') {
|
|
|
544
540
|
|
|
545
541
|
See [Type Documentation](./docs/types.md) for detailed interface definitions of each metadata type.
|
|
546
542
|
|
|
543
|
+
### `GenerationSoftware`
|
|
544
|
+
|
|
545
|
+
String literal union of all supported software identifiers. Used as the key type for `softwareLabels`.
|
|
546
|
+
|
|
547
|
+
```typescript
|
|
548
|
+
type GenerationSoftware =
|
|
549
|
+
| 'novelai' | 'comfyui' | 'swarmui' | 'tensorart' | 'stability-matrix'
|
|
550
|
+
| 'sd-webui' | 'forge' | 'forge-classic' | 'forge-neo'
|
|
551
|
+
| 'reforge'| 'easy-reforge' | 'sd-next' | 'civitai' | 'hf-space'
|
|
552
|
+
| 'invokeai' | 'easydiffusion' | 'fooocus' | 'ruined-fooocus';
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### `EmbedMetadata`
|
|
556
|
+
|
|
557
|
+
User-created custom metadata for the `embed()` and `stringify()` functions. While `GenerationMetadata` represents parsed output from a known AI tool, `EmbedMetadata` is designed for composing metadata from scratch. Extends `BaseMetadata` with optional character prompts and extras.
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
type EmbedMetadata = BaseMetadata &
|
|
561
|
+
Pick<NovelAIMetadata, 'characterPrompts'> & {
|
|
562
|
+
extras?: Record<string, string | number>;
|
|
563
|
+
};
|
|
564
|
+
```
|
|
565
|
+
|
|
547
566
|
### `RawMetadata`
|
|
548
567
|
|
|
549
568
|
Preserves the original metadata structure for round-trip conversions.
|
|
@@ -559,11 +578,14 @@ type RawMetadata =
|
|
|
559
578
|
> For TypeScript users: All types are exported and available for import.
|
|
560
579
|
>
|
|
561
580
|
> ```typescript
|
|
562
|
-
> import type {
|
|
563
|
-
>
|
|
564
|
-
>
|
|
565
|
-
>
|
|
566
|
-
>
|
|
581
|
+
> import type {
|
|
582
|
+
> BaseMetadata,
|
|
583
|
+
> EmbedMetadata,
|
|
584
|
+
> ParseResult,
|
|
585
|
+
> GenerationMetadata,
|
|
586
|
+
> GenerationSoftware,
|
|
587
|
+
> ModelSettings,
|
|
588
|
+
> SamplingSettings
|
|
567
589
|
> } from '@enslo/sd-metadata';
|
|
568
590
|
> ```
|
|
569
591
|
>
|