@enslo/sd-metadata 1.2.0 → 1.3.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 ADDED
@@ -0,0 +1,600 @@
1
+ # sd-metadata
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@enslo/sd-metadata.svg)](https://www.npmjs.com/package/@enslo/sd-metadata)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@enslo/sd-metadata.svg)](https://www.npmjs.com/package/@enslo/sd-metadata)
5
+ [![license](https://img.shields.io/npm/l/@enslo/sd-metadata.svg)](https://github.com/enslo/sd-metadata/blob/main/LICENSE)
6
+
7
+ 🌐 **[English version](./README.md)**
8
+
9
+ AI生成画像に埋め込まれたメタデータを読み書きするためのTypeScriptライブラリです。
10
+
11
+ ## 特徴
12
+
13
+ - **マルチフォーマット対応**: PNG (tEXt / iTXt)、JPEG (COM / Exif)、WebP (Exif)
14
+ - **統一API**: シンプルな `read()` と `write()` 関数で全フォーマットに対応
15
+ - **TypeScriptネイティブ**: TypeScriptで書かれており、型定義を完全同梱
16
+ - **ゼロ依存**: Node.jsとブラウザで外部依存なしで動作
17
+ - **フォーマット変換**: PNG、JPEG、WebP間でメタデータをシームレスに変換
18
+ - **メタデータ保持**: フォーマット変換時に元のメタデータ構造を保持(例:PNG → JPEG → PNG で全データを維持)
19
+
20
+ ## インストール
21
+
22
+ ```bash
23
+ npm install @enslo/sd-metadata
24
+ ```
25
+
26
+ ## ツールサポート
27
+
28
+ | ツール | PNG | JPEG | WebP |
29
+ | ------ | :---: | :----: | :----: |
30
+ | [NovelAI](https://novelai.net/) * | ✅ | 🔄️ | ✅ |
31
+ | [ComfyUI](https://github.com/comfyanonymous/ComfyUI) * | ✅ | 🔄️ | 🔄️ |
32
+ | [AUTOMATIC1111](https://github.com/AUTOMATIC1111/stable-diffusion-webui) | ⚠️ | ⚠️ | ⚠️ |
33
+ | [Forge](https://github.com/lllyasviel/stable-diffusion-webui-forge) / [Forge Neo](https://github.com/neggles/sd-webui-forge-neoforge) | ✅ | ✅ | ✅ |
34
+ | [InvokeAI](https://github.com/invoke-ai/InvokeAI) | ✅ | 🔄️ | 🔄️ |
35
+ | [SwarmUI](https://github.com/Stability-AI/StableSwarmUI) * | ✅ | ✅ | ✅ |
36
+ | [Civitai](https://civitai.com/) | ⚠️ | ✅ | ⚠️ |
37
+ | [TensorArt](https://tensor.art/) | ✅ | 🔄️ | 🔄️ |
38
+ | [Stability Matrix](https://github.com/LykosAI/StabilityMatrix) | ✅ | 🔄️ | 🔄️ |
39
+ | [HuggingFace Space](https://huggingface.co/spaces) | ✅ | 🔄️ | 🔄️ |
40
+ | [Ruined Fooocus](https://github.com/runew0lf/RuinedFooocus) | ✅ | 🔄️ | 🔄️ |
41
+ | [Easy Diffusion](https://github.com/easydiffusion/easydiffusion) | ⚠️ | ⚠️ | ⚠️ |
42
+ | [Fooocus](https://github.com/lllyasviel/Fooocus) | ⚠️ | ⚠️ | ⚠️ |
43
+
44
+ **凡例:**
45
+
46
+ - ✅ **完全対応** - ツールがネイティブでサポートするフォーマット。サンプルファイルで検証済み
47
+ - 🔄️ **拡張対応** - ツールがネイティブでサポートしないフォーマット。sd-metadataがカスタムフォーマット変換により読み書きを可能に。ネイティブフォーマットへのラウンドトリップ変換に対応
48
+ - ⚠️ **実験的** - リファレンスコードやドキュメントの分析により実装。サンプルファイルでの検証は未実施。全てのメタデータフィールドを正しく抽出できない可能性あり
49
+
50
+ **拡張対応の例:**
51
+
52
+ - **Stability Matrix**(ネイティブ: PNGのみ)→ sd-metadataがJPEG/WebPをサポート
53
+ - **NovelAI**(ネイティブ: PNG、WebP)→ sd-metadataがJPEGをサポート
54
+
55
+ ネイティブフォーマットから拡張フォーマットに変換し、再度戻す場合(例:PNG → JPEG → PNG)、全てのメタデータが保持されます。
56
+
57
+ > [!NOTE]
58
+ > \* フォーマット固有の動作があるツール。詳細は[フォーマット固有の動作](#フォーマット固有の動作)を参照してください。
59
+
60
+ > [!TIP]
61
+ > **ツールサポートの拡大にご協力ください!** 実験的なツール(Easy Diffusion、Fooocus)やサポートされていないツールのサンプル画像を募集しています。これらのAIツールで生成したサンプル画像をお持ちの方は、ぜひご提供ください!詳細は[CONTRIBUTING.md](CONTRIBUTING.md)を参照してください。
62
+
63
+ ## フォーマット固有の動作
64
+
65
+ 一部のツールはフォーマット変換時に特定の動作をします:
66
+
67
+ - **ComfyUI JPEG/WebP**: 読み込みは複数のカスタムノードフォーマット(例:`save-image-extended`)に対応していますが、書き込みは情報保持とComfyUIネイティブのドラッグ&ドロップワークフロー読み込みとの互換性のため、常に `comfyui-saveimage-plus` フォーマットを使用します。
68
+ - **NovelAI WebP**: Descriptionフィールドの破損したUTF-8を自動修正します。WebP → PNG → WebP のラウンドトリップは有効で読み取り可能なメタデータを生成しますが、軽微なテキスト修正が含まれます。
69
+ - **SwarmUI PNG→JPEG/WebP**: ネイティブのSwarmUI JPEG/WebPファイルにはノード情報が含まれません。PNGから変換する際、このライブラリは完全なメタデータ保持のためにComfyUIワークフローを `Make` フィールドに保存します(拡張対応)。
70
+
71
+ ## インポート
72
+
73
+ **ESM (TypeScript / Modern JavaScript):**
74
+
75
+ ```typescript
76
+ import { read } from '@enslo/sd-metadata';
77
+ ```
78
+
79
+ **CommonJS (Node.js):**
80
+
81
+ ```javascript
82
+ const { read } = require('@enslo/sd-metadata');
83
+ ```
84
+
85
+ > [!NOTE]
86
+ > 以下の例は全てESM構文を使用しています。CommonJSユーザーは `import` を `require` に置き換えてください。
87
+
88
+ ## 使い方
89
+
90
+ ### Node.jsでの使用
91
+
92
+ ```typescript
93
+ import { read, write } from '@enslo/sd-metadata';
94
+ import { readFileSync, writeFileSync } from 'fs';
95
+
96
+ // サポートされている任意のフォーマットからメタデータを読み込み
97
+ const imageData = readFileSync('image.png');
98
+ const result = read(imageData);
99
+
100
+ if (result.status === 'success') {
101
+ console.log('Tool:', result.metadata.software); // 'novelai', 'comfyui', etc.
102
+ console.log('Prompt:', result.metadata.prompt);
103
+ console.log('Model:', result.metadata.model?.name);
104
+ console.log('Size:', result.metadata.width, 'x', result.metadata.height);
105
+ }
106
+ ```
107
+
108
+ ### ブラウザでの使用
109
+
110
+ ```typescript
111
+ import { read } from '@enslo/sd-metadata';
112
+
113
+ // ファイル入力を処理
114
+ const fileInput = document.querySelector('input[type="file"]');
115
+ fileInput.addEventListener('change', async (e) => {
116
+ const file = e.target.files[0];
117
+ if (!file) return;
118
+
119
+ const arrayBuffer = await file.arrayBuffer();
120
+ const imageData = new Uint8Array(arrayBuffer);
121
+
122
+ const result = read(imageData);
123
+
124
+ if (result.status === 'success') {
125
+ document.getElementById('tool').textContent = result.metadata.software;
126
+ document.getElementById('prompt').textContent = result.metadata.prompt;
127
+ document.getElementById('model').textContent = result.metadata.model?.name || 'N/A';
128
+ }
129
+ });
130
+ ```
131
+
132
+ ### CDN使用(ブックマークレット / ユーザースクリプト)
133
+
134
+ ブックマークレットやユーザースクリプト(Tampermonkey、Violentmonkeyなど)では、jsDelivr CDNから読み込みます:
135
+
136
+ ```javascript
137
+ // CDNからインポート
138
+ import { read } from 'https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@latest/dist/index.js';
139
+
140
+ // 画像を取得してメタデータを読み込み
141
+ const response = await fetch(imageUrl);
142
+ const arrayBuffer = await response.arrayBuffer();
143
+ const imageData = new Uint8Array(arrayBuffer);
144
+
145
+ const result = read(imageData);
146
+ if (result.status === 'success') {
147
+ console.log('Tool:', result.metadata.software);
148
+ console.log('Prompt:', result.metadata.prompt);
149
+ }
150
+ ```
151
+
152
+ > [!TIP]
153
+ > 本番環境では `@latest` の代わりに特定のバージョンを指定してください:
154
+ >
155
+ > ```text
156
+ > https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@1.3.0/dist/index.js
157
+ > ```
158
+
159
+ ### 応用例
160
+
161
+ <details>
162
+ <summary>フォーマット変換</summary>
163
+
164
+ 異なる画像フォーマット間でメタデータを変換:
165
+
166
+ ```typescript
167
+ import { read, write } from '@enslo/sd-metadata';
168
+
169
+ // PNGからメタデータを読み込み
170
+ const pngData = readFileSync('comfyui-output.png');
171
+ const parseResult = read(pngData);
172
+
173
+ if (parseResult.status === 'success') {
174
+ // PNGをJPEGに変換(お好みの画像処理ライブラリを使用)
175
+ const jpegImageData = convertToJpeg(pngData); // 疑似コード:sharp、canvasなどを使用
176
+
177
+ // メタデータをJPEGに埋め込み
178
+ const result = write(jpegImageData, parseResult);
179
+
180
+ if (result.ok) {
181
+ writeFileSync('output.jpg', result.value);
182
+ console.log('画像をメタデータ付きでJPEGに変換しました');
183
+ }
184
+ }
185
+ ```
186
+
187
+ > [!TIP]
188
+ > このライブラリはメタデータの読み書きのみを扱います。実際の画像フォーマット変換(ピクセルのデコード/エンコード)には、[sharp](https://www.npmjs.com/package/sharp)、[jimp](https://www.npmjs.com/package/jimp)、ブラウザCanvas APIなどの画像処理ライブラリを使用してください。
189
+
190
+ </details>
191
+
192
+ <details>
193
+ <summary>読み込み結果のタイプごとの処理</summary>
194
+
195
+ ```typescript
196
+ import { read } from '@enslo/sd-metadata';
197
+
198
+ const result = read(imageData);
199
+
200
+ switch (result.status) {
201
+ case 'success':
202
+ // メタデータのパース成功
203
+ console.log(`Generated by ${result.metadata.software}`);
204
+ console.log(`Prompt: ${result.metadata.prompt}`);
205
+ break;
206
+
207
+ case 'unrecognized':
208
+ // メタデータは存在するがフォーマットが認識できない
209
+ console.log('不明なメタデータフォーマット');
210
+ // デバッグ用に生のメタデータにアクセス可能:
211
+ console.log('Raw chunks:', result.raw);
212
+ break;
213
+
214
+ case 'empty':
215
+ // メタデータが見つからない
216
+ console.log('この画像にはメタデータがありません');
217
+ break;
218
+
219
+ case 'invalid':
220
+ // 破損または無効な画像データ
221
+ console.log('Error:', result.message);
222
+ break;
223
+ }
224
+ ```
225
+
226
+ </details>
227
+
228
+ <details>
229
+ <summary>未対応メタデータの保持</summary>
230
+
231
+ 未対応ツールのメタデータを含む画像を変換する際も、元のメタデータを保持できます:
232
+
233
+ ```typescript
234
+ import { read, write } from '@enslo/sd-metadata';
235
+
236
+ const source = read(unknownImage);
237
+ // source.status === 'unrecognized'
238
+
239
+ // 元のメタデータチャンク/セグメントをそのまま保持
240
+ const result = write(targetImage, source, { force: true });
241
+
242
+ if (result.ok) {
243
+ // 元のメタデータが新しい画像に保持される
244
+ console.log('メタデータの保持に成功しました');
245
+ }
246
+ ```
247
+
248
+ </details>
249
+
250
+ <details>
251
+ <summary>メタデータの削除</summary>
252
+
253
+ 画像から全てのメタデータを削除:
254
+
255
+ ```typescript
256
+ import { write } from '@enslo/sd-metadata';
257
+
258
+ const result = write(imageData, { status: 'empty' });
259
+ if (result.ok) {
260
+ writeFileSync('clean-image.png', result.value);
261
+ }
262
+ ```
263
+
264
+ </details>
265
+
266
+ <details>
267
+ <summary>WebUIフォーマットでメタデータを書き込む</summary>
268
+
269
+ SD WebUI (A1111) フォーマットでカスタムメタデータを作成して埋め込み:
270
+
271
+ ```typescript
272
+ import { writeAsWebUI } from '@enslo/sd-metadata';
273
+
274
+ // カスタムメタデータをゼロから作成
275
+ const metadata = {
276
+ software: 'sd-webui',
277
+ prompt: 'masterpiece, best quality, 1girl',
278
+ negativePrompt: 'lowres, bad quality',
279
+ width: 512,
280
+ height: 768,
281
+ sampling: {
282
+ steps: 20,
283
+ sampler: 'Euler a',
284
+ cfg: 7,
285
+ seed: 12345,
286
+ },
287
+ model: { name: 'model.safetensors' },
288
+ };
289
+
290
+ // 任意の画像フォーマット(PNG、JPEG、WebP)に書き込み
291
+ const result = writeAsWebUI(imageData, metadata);
292
+ if (result.ok) {
293
+ writeFileSync('output.png', result.value);
294
+ }
295
+ ```
296
+
297
+ > [!TIP]
298
+ > `writeAsWebUI` は以下の場合に特に便利です:
299
+ >
300
+ > - プログラムで生成した画像に生成パラメータを埋め込みたい場合
301
+ > - ツール固有フォーマットからWebUI互換フォーマットにメタデータを変換する場合
302
+ > - WebUIで読み取り可能なメタデータを出力するツールを構築する場合
303
+
304
+ </details>
305
+
306
+ <details>
307
+ <summary>表示用にメタデータをフォーマット</summary>
308
+
309
+ **どのツールのメタデータであっても**、統一されたWebUIフォーマットのテキストに変換できます。ツール間の差異(NovelAI、ComfyUI、Forgeなど)を吸収し、一貫したテキスト形式に正規化します:
310
+
311
+ ```typescript
312
+ import { read, formatAsWebUI } from '@enslo/sd-metadata';
313
+
314
+ const result = read(imageData);
315
+ if (result.status === 'success') {
316
+ // どのツールでもOK: NovelAI, ComfyUI, Forge, InvokeAI, etc.
317
+ const text = formatAsWebUI(result.metadata);
318
+ console.log(text);
319
+
320
+ // 常に統一されたWebUIフォーマットで出力:
321
+ // masterpiece, best quality, 1girl
322
+ // Negative prompt: lowres, bad quality
323
+ // Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, Size: 512x768, Model: model.safetensors
324
+ }
325
+ ```
326
+
327
+ > [!NOTE]
328
+ > どのツールで生成された画像であっても、`formatAsWebUI` は共通の生成パラメータを抽出し、標準化された形式に整形します。ツール固有のフォーマットを意識することなく、ユーザーにメタデータを表示するのに最適です。
329
+
330
+ </details>
331
+
332
+ ## APIリファレンス
333
+
334
+ ### `read(data: Uint8Array): ParseResult`
335
+
336
+ 画像ファイルからメタデータを読み込み、パースします。
337
+
338
+ **戻り値:**
339
+
340
+ - `{ status: 'success', metadata, raw }` - パース成功
341
+ - `metadata`: 統一されたメタデータオブジェクト(`GenerationMetadata`を参照)
342
+ - `raw`: 元のフォーマット固有のデータ(chunks/segments)
343
+ - `{ status: 'unrecognized', raw }` - 画像にメタデータがあるが既知のAIツールからではない
344
+ - `raw`: 変換用に保持された元のメタデータ
345
+ - `{ status: 'empty' }` - 画像にメタデータが見つからない
346
+ - `{ status: 'invalid', message? }` - 破損または非対応の画像フォーマット
347
+ - `message`: オプションのエラー説明
348
+
349
+ ### `write(data: Uint8Array, metadata: ParseResult, options?: WriteOptions): WriteResult`
350
+
351
+ 画像ファイルにメタデータを書き込みます。
352
+
353
+ **パラメータ:**
354
+
355
+ - `data` - ターゲット画像ファイルデータ(PNG、JPEG、またはWebP)
356
+ - `metadata` - `read()` から得られた `ParseResult`
357
+ - `status: 'success'` または `'empty'` - 直接書き込み可能
358
+ - `status: 'unrecognized'` - `force: true` オプションが必要
359
+ - `options` - オプション設定:
360
+ - `force?: boolean` - 未対応メタデータの書き込みを有効化(元データをそのまま保持)
361
+
362
+ **戻り値:**
363
+
364
+ - `{ ok: true, value: Uint8Array }` - 書き込み成功(新しい画像データを返す)
365
+ - `{ ok: false, error: { type, message? } }` - 失敗。`type` は以下のいずれか:
366
+ - `'unsupportedFormat'`: 対象画像がPNG、JPEG、WebP以外の場合
367
+ - `'conversionFailed'`: メタデータ変換に失敗(例:互換性のないフォーマット)
368
+ - `'writeFailed'`: 画像へのメタデータ埋め込みに失敗
369
+
370
+ ### `writeAsWebUI(data: Uint8Array, metadata: GenerationMetadata): WriteResult`
371
+
372
+ SD WebUI (A1111) フォーマットで画像にメタデータを書き込みます。
373
+
374
+ **パラメータ:**
375
+
376
+ - `data` - ターゲット画像ファイルデータ(PNG、JPEG、またはWebP)
377
+ - `metadata` - 埋め込む生成メタデータ
378
+ - 任意のツールからでも、カスタム作成でも可能
379
+ - 自動的にWebUIフォーマットに変換される
380
+
381
+ **戻り値:**
382
+
383
+ - `{ ok: true, value: Uint8Array }` - 書き込み成功(新しい画像データを返す)
384
+ - `{ ok: false, error: { type, message? } }` - 失敗。`type` は以下のいずれか:
385
+ - `'unsupportedFormat'`: 対象画像がPNG、JPEG、WebP以外の場合
386
+ - `'writeFailed'`: 画像へのメタデータ埋め込みに失敗
387
+
388
+ **ユースケース:**
389
+
390
+ - プログラムで生成した画像にカスタムメタデータを作成
391
+ - 他のツールからWebUI互換フォーマットにメタデータを変換
392
+ - WebUIで読み取り可能なメタデータを出力するアプリケーションの構築
393
+
394
+ ### `formatAsWebUI(metadata: GenerationMetadata): string`
395
+
396
+ メタデータをSD WebUI (A1111) フォーマットのテキストにフォーマットします。
397
+
398
+ **パラメータ:**
399
+
400
+ - `metadata` - 任意のツールからの生成メタデータ
401
+
402
+ **戻り値:**
403
+
404
+ - WebUIフォーマットの文字列(プレーンテキスト)
405
+
406
+ **出力フォーマット:**
407
+
408
+ ```text
409
+ positive prompt
410
+ [NovelAIのキャラクタープロンプト]
411
+ Negative prompt: negative prompt
412
+ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, Size: 512x768, ...
413
+ ```
414
+
415
+ **ユースケース:**
416
+
417
+ - ユーザーに一貫したフォーマットでメタデータを表示
418
+ - 生成パラメータをテキストとしてコピー
419
+ - 生成設定のログ出力やデバッグ
420
+
421
+ ### `formatRaw(raw: RawMetadata): string`
422
+
423
+ 生のメタデータをプレーンテキストとしてフォーマットします。
424
+
425
+ **パラメータ:**
426
+
427
+ - `raw` - `ParseResult` から得られた生のメタデータ(`result.raw`)
428
+
429
+ **戻り値:**
430
+
431
+ - メタデータのプレーンテキスト内容(複数エントリは空行で区切られる)
432
+
433
+ **ユースケース:**
434
+
435
+ - 認識できないメタデータをユーザーに表示
436
+ - 生のメタデータ内容の素早い確認
437
+ - パース失敗時のフォールバック表示
438
+
439
+ **例:**
440
+
441
+ ```typescript
442
+ import { read, formatAsWebUI, formatRaw } from '@enslo/sd-metadata';
443
+
444
+ const result = read(imageData);
445
+
446
+ switch (result.status) {
447
+ case 'success':
448
+ console.log(formatAsWebUI(result.metadata));
449
+ break;
450
+ case 'unrecognized':
451
+ console.log(formatRaw(result.raw));
452
+ break;
453
+ }
454
+ ```
455
+
456
+ ## 型リファレンス
457
+
458
+ このセクションでは主要な型の概要を説明します。完全な型定義については[型ドキュメント](./docs/types.ja.md)を参照してください。
459
+
460
+ ### `ParseResult`
461
+
462
+ `read()` 関数の結果。`status` フィールドで分岐するユニオン型です。
463
+
464
+ ```typescript
465
+ type ParseResult =
466
+ | { status: 'success'; metadata: GenerationMetadata; raw: RawMetadata }
467
+ | { status: 'unrecognized'; raw: RawMetadata }
468
+ | { status: 'empty' }
469
+ | { status: 'invalid'; message?: string };
470
+ ```
471
+
472
+ ### `GenerationMetadata`
473
+
474
+ `read()` 関数が返す統一されたメタデータ構造。`software` フィールドで区別される3つのメタデータ型のユニオン型です。
475
+
476
+ **共通フィールド(全タイプで利用可能):**
477
+
478
+ 全てのメタデータ型にはこれらの基本フィールドが含まれます:
479
+
480
+ - `prompt: string` - ポジティブプロンプトテキスト
481
+ - `negativePrompt: string` - ネガティブプロンプトテキスト
482
+ - `width: number` - 画像の幅(ピクセル)
483
+ - `height: number` - 画像の高さ(ピクセル)
484
+ - `model?: ModelSettings` - モデル情報(name、hash、VAE)
485
+ - `sampling?: SamplingSettings` - サンプリングパラメータ(seed、steps、CFG、sampler、scheduler、clipSkip)
486
+ - `hires?: HiresSettings` - Hires.fix設定(適用されている場合)
487
+ - `upscale?: UpscaleSettings` - アップスケール設定(適用されている場合)
488
+
489
+ **メタデータ型のバリアント:**
490
+
491
+ - **`NovelAIMetadata`** (`software: 'novelai'`)
492
+ V4キャラクター配置用のNovelAI固有フィールドを含む:
493
+ - `characterPrompts?: CharacterPrompt[]` - キャラクターごとのプロンプトと位置
494
+ - `useCoords?: boolean` - 配置にキャラクター座標を使用
495
+ - `useOrder?: boolean` - キャラクターの順序を使用
496
+
497
+ - **`ComfyUIMetadata`** (`software: 'comfyui' | 'tensorart' | 'stability-matrix' | 'swarmui'`)
498
+ ComfyUIワークフローグラフを含む:
499
+ - `nodes: ComfyNodeGraph`(comfyui/tensorart/stability-matrixでは必須)
500
+ - `nodes?: ComfyNodeGraph`(swarmuiではオプション - PNGフォーマットのみ)
501
+
502
+ - **`StandardMetadata`** (`software: 'sd-webui' | 'forge' | 'invokeai' | 'civitai' | ...`)
503
+ ツール固有の拡張なしのベースラインメタデータ。ほとんどのSD WebUIベースのツールで使用。
504
+
505
+ **型定義:**
506
+
507
+ ```typescript
508
+ type GenerationMetadata =
509
+ | NovelAIMetadata
510
+ | ComfyUIMetadata
511
+ | StandardMetadata;
512
+ ```
513
+
514
+ **使用例:**
515
+
516
+ ```typescript
517
+ const result = read(imageData);
518
+
519
+ if (result.status === 'success') {
520
+ const metadata = result.metadata;
521
+
522
+ // 共通フィールドにアクセス
523
+ console.log('Prompt:', metadata.prompt);
524
+ console.log('Model:', metadata.model?.name);
525
+ console.log('Seed:', metadata.sampling?.seed);
526
+
527
+ // ユニオン型を使用したタイプ固有の処理
528
+ if (metadata.software === 'novelai') {
529
+ // TypeScriptはこれがNovelAIMetadataであることを認識
530
+ console.log('Character prompts:', metadata.characterPrompts);
531
+ } else if (
532
+ metadata.software === 'comfyui' ||
533
+ metadata.software === 'tensorart' ||
534
+ metadata.software === 'stability-matrix'
535
+ ) {
536
+ // TypeScriptはこれがBasicComfyUIMetadata(nodesは常に存在)であることを認識
537
+ console.log('Node count:', Object.keys(metadata.nodes).length);
538
+ } else if (metadata.software === 'swarmui') {
539
+ // TypeScriptはこれがSwarmUIMetadata(nodesはオプション)であることを認識
540
+ if (metadata.nodes) {
541
+ console.log('Workflow included');
542
+ }
543
+ }
544
+ }
545
+ ```
546
+
547
+ 各メタデータ型の詳細なインターフェース定義については[型ドキュメント](./docs/types.ja.md)を参照してください。
548
+
549
+ ### `RawMetadata`
550
+
551
+ ラウンドトリップ変換のために元のメタデータ構造を保持します。
552
+
553
+ ```typescript
554
+ type RawMetadata =
555
+ | { format: 'png'; chunks: PngTextChunk[] }
556
+ | { format: 'jpeg'; segments: MetadataSegment[] }
557
+ | { format: 'webp'; segments: MetadataSegment[] };
558
+ ```
559
+
560
+ > [!TIP]
561
+ > TypeScriptユーザー向け:全ての型はエクスポートされており、インポートして使用できます。
562
+ >
563
+ > ```typescript
564
+ > import type {
565
+ > ParseResult,
566
+ > GenerationMetadata,
567
+ > ModelSettings,
568
+ > SamplingSettings
569
+ > } from '@enslo/sd-metadata';
570
+ > ```
571
+ >
572
+ > IDEのIntelliSenseを使用して自動補完とインラインドキュメントを活用してください。
573
+
574
+ `ModelSettings`、`SamplingSettings`、フォーマット固有の型を含む全てのエクスポート型の詳細なドキュメントについては、[型ドキュメント](./docs/types.ja.md)を参照してください。
575
+
576
+ ## 開発
577
+
578
+ ```bash
579
+ # 依存関係をインストール
580
+ npm install
581
+
582
+ # テストを実行
583
+ npm test
584
+
585
+ # ウォッチモード
586
+ npm run test:watch
587
+
588
+ # テストカバレッジ
589
+ npm run test:coverage
590
+
591
+ # ビルド
592
+ npm run build
593
+
594
+ # リント
595
+ npm run lint
596
+ ```
597
+
598
+ ## ライセンス
599
+
600
+ MIT