@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 +600 -0
- package/README.md +89 -29
- package/dist/index.d.ts +34 -3
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@enslo/sd-metadata)
|
|
5
5
|
[](https://github.com/enslo/sd-metadata/blob/main/LICENSE)
|
|
6
6
|
|
|
7
|
+
๐ฏ๐ต **[ๆฅๆฌ่ช็ใฏใใกใ](./README.ja.md)**
|
|
8
|
+
|
|
7
9
|
A TypeScript library to read and write metadata embedded in AI-generated images.
|
|
8
10
|
|
|
9
11
|
## Features
|
|
@@ -88,7 +90,7 @@ const { read } = require('@enslo/sd-metadata');
|
|
|
88
90
|
### Node.js Usage
|
|
89
91
|
|
|
90
92
|
```typescript
|
|
91
|
-
import { read, write } from 'sd-metadata';
|
|
93
|
+
import { read, write } from '@enslo/sd-metadata';
|
|
92
94
|
import { readFileSync, writeFileSync } from 'fs';
|
|
93
95
|
|
|
94
96
|
// Read metadata from any supported format
|
|
@@ -106,7 +108,7 @@ if (result.status === 'success') {
|
|
|
106
108
|
### Browser Usage
|
|
107
109
|
|
|
108
110
|
```typescript
|
|
109
|
-
import { read } from 'sd-metadata';
|
|
111
|
+
import { read } from '@enslo/sd-metadata';
|
|
110
112
|
|
|
111
113
|
// Handle file input
|
|
112
114
|
const fileInput = document.querySelector('input[type="file"]');
|
|
@@ -151,15 +153,18 @@ if (result.status === 'success') {
|
|
|
151
153
|
> For production use, pin to a specific version instead of `@latest`:
|
|
152
154
|
>
|
|
153
155
|
> ```text
|
|
154
|
-
> https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@1.
|
|
156
|
+
> https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@1.3.0/dist/index.js
|
|
155
157
|
> ```
|
|
156
158
|
|
|
157
|
-
###
|
|
159
|
+
### Advanced Examples
|
|
160
|
+
|
|
161
|
+
<details>
|
|
162
|
+
<summary>Format Conversion</summary>
|
|
158
163
|
|
|
159
164
|
Convert metadata between different image formats:
|
|
160
165
|
|
|
161
166
|
```typescript
|
|
162
|
-
import { read, write } from 'sd-metadata';
|
|
167
|
+
import { read, write } from '@enslo/sd-metadata';
|
|
163
168
|
|
|
164
169
|
// Read metadata from PNG
|
|
165
170
|
const pngData = readFileSync('comfyui-output.png');
|
|
@@ -182,10 +187,13 @@ if (parseResult.status === 'success') {
|
|
|
182
187
|
> [!TIP]
|
|
183
188
|
> This library handles metadata read/write only. For actual image format conversion (decoding/encoding pixels), use image processing libraries like [sharp](https://www.npmjs.com/package/sharp), [jimp](https://www.npmjs.com/package/jimp), or browser Canvas API.
|
|
184
189
|
|
|
185
|
-
|
|
190
|
+
</details>
|
|
191
|
+
|
|
192
|
+
<details>
|
|
193
|
+
<summary>Handling Different Result Types</summary>
|
|
186
194
|
|
|
187
195
|
```typescript
|
|
188
|
-
import { read } from 'sd-metadata';
|
|
196
|
+
import { read } from '@enslo/sd-metadata';
|
|
189
197
|
|
|
190
198
|
const result = read(imageData);
|
|
191
199
|
|
|
@@ -215,31 +223,37 @@ switch (result.status) {
|
|
|
215
223
|
}
|
|
216
224
|
```
|
|
217
225
|
|
|
218
|
-
|
|
226
|
+
</details>
|
|
219
227
|
|
|
220
|
-
|
|
228
|
+
<details>
|
|
229
|
+
<summary>Preserving Unrecognized Metadata</summary>
|
|
230
|
+
|
|
231
|
+
When converting images with metadata from unsupported tools, you can still preserve the original metadata:
|
|
221
232
|
|
|
222
233
|
```typescript
|
|
223
|
-
import { read, write } from 'sd-metadata';
|
|
234
|
+
import { read, write } from '@enslo/sd-metadata';
|
|
224
235
|
|
|
225
236
|
const source = read(unknownImage);
|
|
226
237
|
// source.status === 'unrecognized'
|
|
227
238
|
|
|
228
|
-
//
|
|
239
|
+
// Preserve all original metadata chunks/segments
|
|
229
240
|
const result = write(targetImage, source, { force: true });
|
|
230
241
|
|
|
231
242
|
if (result.ok) {
|
|
232
|
-
//
|
|
233
|
-
console.log('
|
|
243
|
+
// Original metadata preserved in the new image
|
|
244
|
+
console.log('Metadata preserved successfully');
|
|
234
245
|
}
|
|
235
246
|
```
|
|
236
247
|
|
|
237
|
-
|
|
248
|
+
</details>
|
|
249
|
+
|
|
250
|
+
<details>
|
|
251
|
+
<summary>Removing Metadata</summary>
|
|
238
252
|
|
|
239
253
|
To strip all metadata from an image:
|
|
240
254
|
|
|
241
255
|
```typescript
|
|
242
|
-
import { write } from 'sd-metadata';
|
|
256
|
+
import { write } from '@enslo/sd-metadata';
|
|
243
257
|
|
|
244
258
|
const result = write(imageData, { status: 'empty' });
|
|
245
259
|
if (result.ok) {
|
|
@@ -247,12 +261,15 @@ if (result.ok) {
|
|
|
247
261
|
}
|
|
248
262
|
```
|
|
249
263
|
|
|
250
|
-
|
|
264
|
+
</details>
|
|
265
|
+
|
|
266
|
+
<details>
|
|
267
|
+
<summary>Writing Metadata in WebUI Format</summary>
|
|
251
268
|
|
|
252
269
|
Create and embed custom metadata in SD WebUI (A1111) format:
|
|
253
270
|
|
|
254
271
|
```typescript
|
|
255
|
-
import { writeAsWebUI } from 'sd-metadata';
|
|
272
|
+
import { writeAsWebUI } from '@enslo/sd-metadata';
|
|
256
273
|
|
|
257
274
|
// Create custom metadata from scratch
|
|
258
275
|
const metadata = {
|
|
@@ -284,20 +301,23 @@ if (result.ok) {
|
|
|
284
301
|
> - Converting metadata from proprietary formats to WebUI-compatible format
|
|
285
302
|
> - Building tools that need to output WebUI-readable metadata
|
|
286
303
|
|
|
287
|
-
|
|
304
|
+
</details>
|
|
305
|
+
|
|
306
|
+
<details>
|
|
307
|
+
<summary>Formatting Metadata for Display</summary>
|
|
288
308
|
|
|
289
|
-
Convert metadata to human-readable
|
|
309
|
+
Convert metadata from **any supported tool** to a unified, human-readable WebUI format. This normalizes the differences between tools (NovelAI, ComfyUI, Forge, etc.) into a consistent text format:
|
|
290
310
|
|
|
291
311
|
```typescript
|
|
292
|
-
import { read, formatAsWebUI } from 'sd-metadata';
|
|
312
|
+
import { read, formatAsWebUI } from '@enslo/sd-metadata';
|
|
293
313
|
|
|
294
314
|
const result = read(imageData);
|
|
295
315
|
if (result.status === 'success') {
|
|
296
|
-
//
|
|
316
|
+
// Works with any tool: NovelAI, ComfyUI, Forge, InvokeAI, etc.
|
|
297
317
|
const text = formatAsWebUI(result.metadata);
|
|
298
318
|
console.log(text);
|
|
299
319
|
|
|
300
|
-
//
|
|
320
|
+
// Always outputs in consistent WebUI format:
|
|
301
321
|
// masterpiece, best quality, 1girl
|
|
302
322
|
// Negative prompt: lowres, bad quality
|
|
303
323
|
// Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, Size: 512x768, Model: model.safetensors
|
|
@@ -305,7 +325,9 @@ if (result.status === 'success') {
|
|
|
305
325
|
```
|
|
306
326
|
|
|
307
327
|
> [!NOTE]
|
|
308
|
-
> `formatAsWebUI`
|
|
328
|
+
> 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.
|
|
329
|
+
|
|
330
|
+
</details>
|
|
309
331
|
|
|
310
332
|
## API Reference
|
|
311
333
|
|
|
@@ -335,13 +357,15 @@ Writes metadata to an image file.
|
|
|
335
357
|
- `status: 'success'` or `'empty'` - Can write directly
|
|
336
358
|
- `status: 'unrecognized'` - Requires `force: true` option
|
|
337
359
|
- `options` - Optional settings:
|
|
338
|
-
- `force?: boolean` -
|
|
360
|
+
- `force?: boolean` - Enables writing unrecognized metadata (preserves original data as-is)
|
|
339
361
|
|
|
340
362
|
**Returns:**
|
|
341
363
|
|
|
342
364
|
- `{ ok: true, value: Uint8Array }` - Successfully written (returns new image data)
|
|
343
|
-
- `{ ok: false, error: { type
|
|
344
|
-
- `
|
|
365
|
+
- `{ ok: false, error: { type, message? } }` - Failed. `type` is one of:
|
|
366
|
+
- `'unsupportedFormat'`: Target image is not PNG, JPEG, or WebP
|
|
367
|
+
- `'conversionFailed'`: Metadata conversion failed (e.g., incompatible format)
|
|
368
|
+
- `'writeFailed'`: Failed to embed metadata into the image
|
|
345
369
|
|
|
346
370
|
### `writeAsWebUI(data: Uint8Array, metadata: GenerationMetadata): WriteResult`
|
|
347
371
|
|
|
@@ -357,8 +381,9 @@ Writes metadata to an image in SD WebUI (A1111) format.
|
|
|
357
381
|
**Returns:**
|
|
358
382
|
|
|
359
383
|
- `{ ok: true, value: Uint8Array }` - Successfully written (returns new image data)
|
|
360
|
-
- `{ ok: false, error: { type
|
|
361
|
-
- `
|
|
384
|
+
- `{ ok: false, error: { type, message? } }` - Failed. `type` is one of:
|
|
385
|
+
- `'unsupportedFormat'`: Target image is not PNG, JPEG, or WebP
|
|
386
|
+
- `'writeFailed'`: Failed to embed metadata into the image
|
|
362
387
|
|
|
363
388
|
**Use cases:**
|
|
364
389
|
|
|
@@ -393,6 +418,41 @@ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 12345, Size: 512x768, ...
|
|
|
393
418
|
- Copying generation parameters as text
|
|
394
419
|
- Logging or debugging generation settings
|
|
395
420
|
|
|
421
|
+
### `formatRaw(raw: RawMetadata): string`
|
|
422
|
+
|
|
423
|
+
Formats raw metadata as plain text.
|
|
424
|
+
|
|
425
|
+
**Parameters:**
|
|
426
|
+
|
|
427
|
+
- `raw` - Raw metadata from `ParseResult` (`result.raw`)
|
|
428
|
+
|
|
429
|
+
**Returns:**
|
|
430
|
+
|
|
431
|
+
- Plain text content from the metadata (multiple entries separated by blank lines)
|
|
432
|
+
|
|
433
|
+
**Use cases:**
|
|
434
|
+
|
|
435
|
+
- Displaying unrecognized metadata to users
|
|
436
|
+
- Quick inspection of raw metadata content
|
|
437
|
+
- Fallback display when parsing fails
|
|
438
|
+
|
|
439
|
+
**Example:**
|
|
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
|
+
|
|
396
456
|
## Type Reference
|
|
397
457
|
|
|
398
458
|
This section provides an overview of the main types. For complete type definitions, see [Type Documentation](./docs/types.md).
|
|
@@ -511,7 +571,7 @@ type RawMetadata =
|
|
|
511
571
|
>
|
|
512
572
|
> Use your IDE's IntelliSense for auto-completion and inline documentation.
|
|
513
573
|
|
|
514
|
-
For detailed documentation of all exported types including `
|
|
574
|
+
For detailed documentation of all exported types including `ModelSettings`, `SamplingSettings`, and format-specific types, see the [Type Documentation](./docs/types.md).
|
|
515
575
|
|
|
516
576
|
## Development
|
|
517
577
|
|
package/dist/index.d.ts
CHANGED
|
@@ -397,7 +397,7 @@ declare function write(data: Uint8Array, metadata: ParseResult, options?: WriteO
|
|
|
397
397
|
*
|
|
398
398
|
* @example
|
|
399
399
|
* ```typescript
|
|
400
|
-
* import { writeAsWebUI } from 'sd-metadata';
|
|
400
|
+
* import { writeAsWebUI } from '@enslo/sd-metadata';
|
|
401
401
|
*
|
|
402
402
|
* // Create custom metadata
|
|
403
403
|
* const metadata = {
|
|
@@ -445,7 +445,7 @@ declare function writeAsWebUI(data: Uint8Array, metadata: GenerationMetadata): W
|
|
|
445
445
|
*
|
|
446
446
|
* @example
|
|
447
447
|
* ```typescript
|
|
448
|
-
* import { read, formatAsWebUI } from 'sd-metadata';
|
|
448
|
+
* import { read, formatAsWebUI } from '@enslo/sd-metadata';
|
|
449
449
|
*
|
|
450
450
|
* const result = read(imageData);
|
|
451
451
|
* if (result.status === 'success') {
|
|
@@ -460,4 +460,35 @@ declare function writeAsWebUI(data: Uint8Array, metadata: GenerationMetadata): W
|
|
|
460
460
|
*/
|
|
461
461
|
declare function formatAsWebUI(metadata: GenerationMetadata): string;
|
|
462
462
|
|
|
463
|
-
|
|
463
|
+
/**
|
|
464
|
+
* Raw metadata serialization utilities
|
|
465
|
+
*
|
|
466
|
+
* Formats RawMetadata as human-readable plain text.
|
|
467
|
+
*/
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Format raw metadata as plain text
|
|
471
|
+
*
|
|
472
|
+
* Extracts text content from RawMetadata and returns it as a simple string.
|
|
473
|
+
* Multiple entries are separated by double newlines.
|
|
474
|
+
*
|
|
475
|
+
* This is useful for displaying unrecognized metadata to end users
|
|
476
|
+
* without needing to manually iterate over chunks or segments.
|
|
477
|
+
*
|
|
478
|
+
* @param raw - Raw metadata from ParseResult
|
|
479
|
+
* @returns Plain text content from the metadata
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* ```typescript
|
|
483
|
+
* import { read, formatRaw } from '@enslo/sd-metadata';
|
|
484
|
+
*
|
|
485
|
+
* const result = read(imageData);
|
|
486
|
+
* if (result.status === 'unrecognized') {
|
|
487
|
+
* console.log(formatRaw(result.raw));
|
|
488
|
+
* // Output: the raw text content without prefixes
|
|
489
|
+
* }
|
|
490
|
+
* ```
|
|
491
|
+
*/
|
|
492
|
+
declare function formatRaw(raw: RawMetadata): string;
|
|
493
|
+
|
|
494
|
+
export { type CharacterPrompt, type GenerationMetadata, type HiresSettings, type ITXtChunk, type MetadataSegment, type MetadataSegmentSource, type ModelSettings, type ParseResult, type PngTextChunk, type RawMetadata, type SamplingSettings, type TExtChunk, type UpscaleSettings, type WriteOptions, type WriteResult, formatAsWebUI, formatRaw, read, write, writeAsWebUI };
|
package/dist/index.js
CHANGED
|
@@ -3012,8 +3012,20 @@ function createExifSegments(text) {
|
|
|
3012
3012
|
}
|
|
3013
3013
|
];
|
|
3014
3014
|
}
|
|
3015
|
+
|
|
3016
|
+
// src/serializers/raw.ts
|
|
3017
|
+
function formatRaw(raw) {
|
|
3018
|
+
switch (raw.format) {
|
|
3019
|
+
case "png":
|
|
3020
|
+
return raw.chunks.map((chunk) => chunk.text).join("\n\n");
|
|
3021
|
+
case "jpeg":
|
|
3022
|
+
case "webp":
|
|
3023
|
+
return raw.segments.map((segment) => segment.data).join("\n\n");
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3015
3026
|
export {
|
|
3016
3027
|
formatAsWebUI,
|
|
3028
|
+
formatRaw,
|
|
3017
3029
|
read,
|
|
3018
3030
|
write,
|
|
3019
3031
|
writeAsWebUI
|