@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/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
* PNG text chunk (tEXt or iTXt)
|
|
3
3
|
*/
|
|
4
4
|
type PngTextChunk = TExtChunk | ITXtChunk;
|
|
5
|
+
/**
|
|
6
|
+
* tEXt chunk (Latin-1 encoded text)
|
|
7
|
+
*/
|
|
8
|
+
interface TExtChunk {
|
|
9
|
+
type: 'tEXt';
|
|
10
|
+
/** Chunk keyword (e.g., 'parameters', 'Comment') */
|
|
11
|
+
keyword: string;
|
|
12
|
+
/** Text content */
|
|
13
|
+
text: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* iTXt chunk (UTF-8 encoded international text)
|
|
17
|
+
*/
|
|
18
|
+
interface ITXtChunk {
|
|
19
|
+
type: 'iTXt';
|
|
20
|
+
/** Chunk keyword */
|
|
21
|
+
keyword: string;
|
|
22
|
+
/** Compression flag (0=uncompressed, 1=compressed) */
|
|
23
|
+
compressionFlag: number;
|
|
24
|
+
/** Compression method (0=zlib/deflate) */
|
|
25
|
+
compressionMethod: number;
|
|
26
|
+
/** Language tag (BCP 47) */
|
|
27
|
+
languageTag: string;
|
|
28
|
+
/** Translated keyword */
|
|
29
|
+
translatedKeyword: string;
|
|
30
|
+
/** Text content */
|
|
31
|
+
text: string;
|
|
32
|
+
}
|
|
5
33
|
/**
|
|
6
34
|
* Source location of a metadata segment.
|
|
7
35
|
* Used for round-tripping: reading and writing back to the correct location.
|
|
@@ -40,33 +68,9 @@ type RawMetadata = {
|
|
|
40
68
|
segments: MetadataSegment[];
|
|
41
69
|
};
|
|
42
70
|
/**
|
|
43
|
-
*
|
|
44
|
-
*/
|
|
45
|
-
interface TExtChunk {
|
|
46
|
-
type: 'tEXt';
|
|
47
|
-
/** Chunk keyword (e.g., 'parameters', 'Comment') */
|
|
48
|
-
keyword: string;
|
|
49
|
-
/** Text content */
|
|
50
|
-
text: string;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* iTXt chunk (UTF-8 encoded international text)
|
|
71
|
+
* Known AI image generation software
|
|
54
72
|
*/
|
|
55
|
-
|
|
56
|
-
type: 'iTXt';
|
|
57
|
-
/** Chunk keyword */
|
|
58
|
-
keyword: string;
|
|
59
|
-
/** Compression flag (0=uncompressed, 1=compressed) */
|
|
60
|
-
compressionFlag: number;
|
|
61
|
-
/** Compression method (0=zlib/deflate) */
|
|
62
|
-
compressionMethod: number;
|
|
63
|
-
/** Language tag (BCP 47) */
|
|
64
|
-
languageTag: string;
|
|
65
|
-
/** Translated keyword */
|
|
66
|
-
translatedKeyword: string;
|
|
67
|
-
/** Text content */
|
|
68
|
-
text: string;
|
|
69
|
-
}
|
|
73
|
+
type GenerationSoftware = 'novelai' | 'comfyui' | 'swarmui' | 'tensorart' | 'stability-matrix' | 'invokeai' | 'forge' | 'forge-classic' | 'forge-neo' | 'reforge' | 'easy-reforge' | 'sd-webui' | 'sd-next' | 'civitai' | 'hf-space' | 'easydiffusion' | 'fooocus' | 'ruined-fooocus';
|
|
70
74
|
/**
|
|
71
75
|
* Base metadata fields shared by all tools
|
|
72
76
|
*/
|
|
@@ -196,7 +200,7 @@ type ComfyUIMetadata = BasicComfyUIMetadata | SwarmUIMetadata;
|
|
|
196
200
|
* NovelAI's character prompts or ComfyUI's node graphs.
|
|
197
201
|
*/
|
|
198
202
|
interface StandardMetadata extends BaseMetadata {
|
|
199
|
-
software: 'sd-webui' | 'sd-next' | 'forge' | 'forge-neo' | 'invokeai' | 'civitai' | 'hf-space' | 'easydiffusion' | 'fooocus' | 'ruined-fooocus';
|
|
203
|
+
software: 'sd-webui' | 'sd-next' | 'forge' | 'forge-classic' | 'forge-neo' | 'reforge' | 'easy-reforge' | 'invokeai' | 'civitai' | 'hf-space' | 'easydiffusion' | 'fooocus' | 'ruined-fooocus';
|
|
200
204
|
}
|
|
201
205
|
/**
|
|
202
206
|
* Unified generation metadata (discriminated union)
|
|
@@ -215,6 +219,18 @@ interface StandardMetadata extends BaseMetadata {
|
|
|
215
219
|
* ```
|
|
216
220
|
*/
|
|
217
221
|
type GenerationMetadata = NovelAIMetadata | ComfyUIMetadata | StandardMetadata;
|
|
222
|
+
/**
|
|
223
|
+
* User-created custom metadata for the embed() and stringify() APIs
|
|
224
|
+
*
|
|
225
|
+
* While {@link GenerationMetadata} represents parsed output from a known AI tool,
|
|
226
|
+
* EmbedMetadata is designed for users to compose their own metadata from
|
|
227
|
+
* scratch. Includes all base generation fields plus optional character
|
|
228
|
+
* prompts and extras for the settings line.
|
|
229
|
+
*/
|
|
230
|
+
type EmbedMetadata = BaseMetadata & Pick<NovelAIMetadata, 'characterPrompts'> & {
|
|
231
|
+
/** Additional key-value pairs for the settings line */
|
|
232
|
+
extras?: Record<string, string | number>;
|
|
233
|
+
};
|
|
218
234
|
/**
|
|
219
235
|
* Model settings
|
|
220
236
|
*/
|
|
@@ -288,15 +304,9 @@ type ParseResult = {
|
|
|
288
304
|
status: 'invalid';
|
|
289
305
|
message?: string;
|
|
290
306
|
};
|
|
291
|
-
|
|
292
307
|
/**
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
* Handles reading and parsing metadata from images.
|
|
296
|
-
* Automatically detects image format and extracts embedded generation metadata.
|
|
308
|
+
* Options for the read function
|
|
297
309
|
*/
|
|
298
|
-
|
|
299
|
-
/** Options for the read function */
|
|
300
310
|
interface ReadOptions {
|
|
301
311
|
/**
|
|
302
312
|
* When true, dimensions are taken strictly from metadata only.
|
|
@@ -305,25 +315,6 @@ interface ReadOptions {
|
|
|
305
315
|
*/
|
|
306
316
|
strict?: boolean;
|
|
307
317
|
}
|
|
308
|
-
/**
|
|
309
|
-
* Read and parse metadata from an image
|
|
310
|
-
*
|
|
311
|
-
* Automatically detects the image format (PNG, JPEG, WebP) and parses
|
|
312
|
-
* any embedded generation metadata.
|
|
313
|
-
*
|
|
314
|
-
* @param input - Image file data (Uint8Array or ArrayBuffer)
|
|
315
|
-
* @param options - Read options
|
|
316
|
-
* @returns Parse result containing metadata and raw data
|
|
317
|
-
*/
|
|
318
|
-
declare function read(input: Uint8Array | ArrayBuffer, options?: ReadOptions): ParseResult;
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Write API for sd-metadata
|
|
322
|
-
*
|
|
323
|
-
* Handles writing metadata to images with automatic format conversion.
|
|
324
|
-
* Supports PNG, JPEG, and WebP formats.
|
|
325
|
-
*/
|
|
326
|
-
|
|
327
318
|
/**
|
|
328
319
|
* Warning types for write operations
|
|
329
320
|
*/
|
|
@@ -356,50 +347,39 @@ type WriteResult = {
|
|
|
356
347
|
ok: false;
|
|
357
348
|
error: WriteError;
|
|
358
349
|
};
|
|
359
|
-
/**
|
|
360
|
-
* Write metadata to an image
|
|
361
|
-
*
|
|
362
|
-
* Automatically detects the target image format and converts the metadata
|
|
363
|
-
* if necessary. For unrecognized metadata with cross-format conversion,
|
|
364
|
-
* metadata is dropped and a warning is returned.
|
|
365
|
-
*
|
|
366
|
-
* @param input - Target image file data (Uint8Array or ArrayBuffer)
|
|
367
|
-
* @param metadata - ParseResult from `read()`
|
|
368
|
-
* @returns New image data with embedded metadata (or warning if metadata was dropped)
|
|
369
|
-
*/
|
|
370
|
-
declare function write(input: Uint8Array | ArrayBuffer, metadata: ParseResult): WriteResult;
|
|
371
350
|
|
|
372
351
|
/**
|
|
373
|
-
*
|
|
352
|
+
* Embed API for sd-metadata
|
|
374
353
|
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
354
|
+
* Write user-created or parsed metadata in A1111 format to PNG, JPEG,
|
|
355
|
+
* or WebP images. Accepts both EmbedMetadata (custom metadata composed
|
|
356
|
+
* by the user) and GenerationMetadata (parsed output from AI tools).
|
|
377
357
|
*/
|
|
378
358
|
|
|
379
359
|
/**
|
|
380
|
-
*
|
|
360
|
+
* Embed metadata into an image
|
|
381
361
|
*
|
|
382
|
-
* Converts the provided
|
|
383
|
-
*
|
|
384
|
-
* -
|
|
385
|
-
*
|
|
386
|
-
*
|
|
362
|
+
* Converts the provided metadata to A1111 plain text format and embeds it
|
|
363
|
+
* into the image. Accepts {@link EmbedMetadata} for user-created custom metadata, or
|
|
364
|
+
* {@link GenerationMetadata} for re-embedding parsed output from any AI tool.
|
|
365
|
+
*
|
|
366
|
+
* Extras (`metadata.extras`) allow adding arbitrary key-value pairs to the
|
|
367
|
+
* settings line. If an extras key matches a structured field (e.g., "Steps"),
|
|
368
|
+
* the extras value overrides the structured value at its original position.
|
|
387
369
|
*
|
|
388
370
|
* The metadata is stored differently based on image format:
|
|
389
371
|
* - PNG: `parameters` tEXt/iTXt chunk (encoding auto-selected based on content)
|
|
390
372
|
* - JPEG/WebP: Exif UserComment field
|
|
391
373
|
*
|
|
392
374
|
* @param input - Target image file data (Uint8Array or ArrayBuffer)
|
|
393
|
-
* @param metadata -
|
|
375
|
+
* @param metadata - Metadata to embed (EmbedMetadata or GenerationMetadata)
|
|
394
376
|
* @returns New image data with embedded metadata, or error
|
|
395
377
|
*
|
|
396
378
|
* @example
|
|
397
379
|
* ```typescript
|
|
398
|
-
* import {
|
|
380
|
+
* import { embed } from '@enslo/sd-metadata';
|
|
399
381
|
*
|
|
400
|
-
* // Create custom metadata
|
|
401
382
|
* const metadata = {
|
|
402
|
-
* software: 'sd-webui',
|
|
403
383
|
* prompt: 'masterpiece, 1girl',
|
|
404
384
|
* negativePrompt: 'lowres, bad quality',
|
|
405
385
|
* width: 512,
|
|
@@ -408,85 +388,139 @@ declare function write(input: Uint8Array | ArrayBuffer, metadata: ParseResult):
|
|
|
408
388
|
* model: { name: 'model.safetensors' },
|
|
409
389
|
* };
|
|
410
390
|
*
|
|
411
|
-
* // Embed
|
|
412
|
-
* const result =
|
|
391
|
+
* // Embed with custom extras
|
|
392
|
+
* const result = embed(imageData, {
|
|
393
|
+
* ...metadata,
|
|
394
|
+
* extras: { Version: 'v1.10.0', 'Lora hashes': 'abc123' },
|
|
395
|
+
* });
|
|
396
|
+
*
|
|
413
397
|
* if (result.ok) {
|
|
414
398
|
* writeFileSync('output.png', result.value);
|
|
415
399
|
* }
|
|
416
400
|
* ```
|
|
417
401
|
*/
|
|
418
|
-
declare function
|
|
402
|
+
declare function embed(input: Uint8Array | ArrayBuffer, metadata: EmbedMetadata | GenerationMetadata): WriteResult;
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Read API for sd-metadata
|
|
406
|
+
*
|
|
407
|
+
* Handles reading and parsing metadata from images.
|
|
408
|
+
* Automatically detects image format and extracts embedded generation metadata.
|
|
409
|
+
*/
|
|
419
410
|
|
|
420
411
|
/**
|
|
421
|
-
*
|
|
412
|
+
* Read and parse metadata from an image
|
|
422
413
|
*
|
|
423
|
-
*
|
|
414
|
+
* Automatically detects the image format (PNG, JPEG, WebP) and parses
|
|
415
|
+
* any embedded generation metadata.
|
|
416
|
+
*
|
|
417
|
+
* @param input - Image file data (Uint8Array or ArrayBuffer)
|
|
418
|
+
* @param options - Read options
|
|
419
|
+
* @returns Parse result containing metadata and raw data
|
|
424
420
|
*/
|
|
421
|
+
declare function read(input: Uint8Array | ArrayBuffer, options?: ReadOptions): ParseResult;
|
|
425
422
|
|
|
426
423
|
/**
|
|
427
|
-
*
|
|
424
|
+
* Unified metadata stringification
|
|
428
425
|
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
|
|
426
|
+
* Builds A1111-format plain text from metadata and provides the stringify()
|
|
427
|
+
* public API for converting any metadata type to a human-readable string.
|
|
428
|
+
*/
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Build A1111-format text from EmbedMetadata
|
|
432
432
|
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
* Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, ...
|
|
439
|
-
* ```
|
|
433
|
+
* Output structure:
|
|
434
|
+
* 1. Positive prompt (line-ending normalized)
|
|
435
|
+
* 2. Character prompts (if present)
|
|
436
|
+
* 3. Negative prompt (if non-empty)
|
|
437
|
+
* 4. Settings line (structured fields + extras)
|
|
440
438
|
*
|
|
441
|
-
* @param metadata -
|
|
442
|
-
* @returns
|
|
439
|
+
* @param metadata - Embed metadata (extras included via `metadata.extras`)
|
|
440
|
+
* @returns A1111-format plain text
|
|
441
|
+
*/
|
|
442
|
+
declare function buildEmbedText(metadata: EmbedMetadata): string;
|
|
443
|
+
/**
|
|
444
|
+
* Format raw metadata as plain text
|
|
445
|
+
*
|
|
446
|
+
* Extracts text content from RawMetadata and returns it as a simple string.
|
|
447
|
+
* Multiple entries are separated by double newlines.
|
|
448
|
+
*
|
|
449
|
+
* @param raw - Raw metadata from ParseResult
|
|
450
|
+
* @returns Plain text content from the metadata
|
|
451
|
+
*/
|
|
452
|
+
declare function formatRaw(raw: RawMetadata): string;
|
|
453
|
+
/**
|
|
454
|
+
* Convert metadata to a human-readable string
|
|
455
|
+
*
|
|
456
|
+
* Accepts multiple input types:
|
|
457
|
+
* - `ParseResult`: Automatically selects the best representation based on status
|
|
458
|
+
* - `GenerationMetadata`: Formats as A1111 text (parsed metadata from any tool)
|
|
459
|
+
* - `EmbedMetadata`: Formats as A1111 text (user-created custom metadata)
|
|
460
|
+
*
|
|
461
|
+
* @param input - Parse result, generation metadata, or embed metadata
|
|
462
|
+
* @returns Human-readable text representation, or empty string if no data
|
|
443
463
|
*
|
|
444
464
|
* @example
|
|
445
465
|
* ```typescript
|
|
446
|
-
* import { read,
|
|
466
|
+
* import { read, stringify } from '@enslo/sd-metadata';
|
|
447
467
|
*
|
|
468
|
+
* // From parse result
|
|
448
469
|
* const result = read(imageData);
|
|
470
|
+
* const text = stringify(result);
|
|
471
|
+
*
|
|
472
|
+
* // From GenerationMetadata (e.g. after parsing)
|
|
449
473
|
* if (result.status === 'success') {
|
|
450
|
-
* const
|
|
451
|
-
* console.log(text);
|
|
452
|
-
* // Output:
|
|
453
|
-
* // masterpiece, 1girl
|
|
454
|
-
* // Negative prompt: low quality, bad anatomy
|
|
455
|
-
* // Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, Size: 512x768, Model: model.safetensors
|
|
474
|
+
* const text3 = stringify(result.metadata);
|
|
456
475
|
* }
|
|
476
|
+
*
|
|
477
|
+
* // From EmbedMetadata (e.g. user-created)
|
|
478
|
+
* const text2 = stringify({
|
|
479
|
+
* prompt: 'masterpiece, 1girl',
|
|
480
|
+
* negativePrompt: '',
|
|
481
|
+
* width: 512,
|
|
482
|
+
* height: 768,
|
|
483
|
+
* sampling: { steps: 20, sampler: 'Euler a', cfg: 7, seed: 12345 },
|
|
484
|
+
* extras: { Version: 'v1.10.0' },
|
|
485
|
+
* });
|
|
457
486
|
* ```
|
|
458
487
|
*/
|
|
459
|
-
declare function
|
|
488
|
+
declare function stringify(input: ParseResult | EmbedMetadata | GenerationMetadata): string;
|
|
460
489
|
|
|
461
490
|
/**
|
|
462
|
-
*
|
|
491
|
+
* Write API for sd-metadata
|
|
463
492
|
*
|
|
464
|
-
*
|
|
493
|
+
* Handles writing metadata to images with automatic format conversion.
|
|
494
|
+
* Supports PNG, JPEG, and WebP formats.
|
|
465
495
|
*/
|
|
466
496
|
|
|
467
497
|
/**
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
* Extracts text content from RawMetadata and returns it as a simple string.
|
|
471
|
-
* Multiple entries are separated by double newlines.
|
|
498
|
+
* Write metadata to an image
|
|
472
499
|
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
500
|
+
* Automatically detects the target image format and converts the metadata
|
|
501
|
+
* if necessary. For unrecognized metadata with cross-format conversion,
|
|
502
|
+
* metadata is dropped and a warning is returned.
|
|
475
503
|
*
|
|
476
|
-
* @param
|
|
477
|
-
* @
|
|
504
|
+
* @param input - Target image file data (Uint8Array or ArrayBuffer)
|
|
505
|
+
* @param metadata - ParseResult from `read()`
|
|
506
|
+
* @returns New image data with embedded metadata (or warning if metadata was dropped)
|
|
507
|
+
*/
|
|
508
|
+
declare function write(input: Uint8Array | ArrayBuffer, metadata: ParseResult): WriteResult;
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Human-readable display labels for each generation software identifier.
|
|
478
512
|
*
|
|
479
513
|
* @example
|
|
480
514
|
* ```typescript
|
|
481
|
-
* import {
|
|
515
|
+
* import { softwareLabels } from '@enslo/sd-metadata';
|
|
482
516
|
*
|
|
483
517
|
* const result = read(imageData);
|
|
484
|
-
* if (result.status === '
|
|
485
|
-
* console.log(
|
|
486
|
-
* //
|
|
518
|
+
* if (result.status === 'success') {
|
|
519
|
+
* console.log(softwareLabels[result.metadata.software]);
|
|
520
|
+
* // => "NovelAI", "ComfyUI", "Stable Diffusion WebUI", etc.
|
|
487
521
|
* }
|
|
488
522
|
* ```
|
|
489
523
|
*/
|
|
490
|
-
declare
|
|
524
|
+
declare const softwareLabels: Readonly<Record<GenerationSoftware, string>>;
|
|
491
525
|
|
|
492
|
-
export { type CharacterPrompt, type ComfyNode, type ComfyNodeGraph, type ComfyNodeInputValue, type ComfyNodeReference, type GenerationMetadata, type HiresSettings, type ITXtChunk, type MetadataSegment, type MetadataSegmentSource, type ModelSettings, type ParseResult, type PngTextChunk, type RawMetadata, type ReadOptions, type SamplingSettings, type TExtChunk, type UpscaleSettings, type WriteResult, type WriteWarning, formatAsWebUI, formatRaw, read, write, writeAsWebUI };
|
|
526
|
+
export { type BaseMetadata, type CharacterPrompt, type ComfyNode, type ComfyNodeGraph, type ComfyNodeInputValue, type ComfyNodeReference, type EmbedMetadata, type GenerationMetadata, type GenerationSoftware, type HiresSettings, type ITXtChunk, type MetadataSegment, type MetadataSegmentSource, type ModelSettings, type ParseResult, type PngTextChunk, type RawMetadata, type ReadOptions, type SamplingSettings, type TExtChunk, type UpscaleSettings, type WriteResult, type WriteWarning, embed, buildEmbedText as formatAsWebUI, formatRaw, read, softwareLabels, stringify, write, embed as writeAsWebUI };
|