@enslo/sd-metadata (英语)
🌐 日本語版はこちら
🔗 现场直播
一个TypeScript库来读取并写入嵌入到AI生成的图像中的元数据.
特征
- 多形式支助: PNG (tEXt / iTXt / eXIF), JPEG (COM / Exif), WebP (Exif), 加上 MP4 / MOV 和 WebM / MKV 视频(只读)
- 简单 API数字 :
parse(), (中文(简体) ),write(), (中文(简体) ),embed(), (中文(简体) ),stringify()四种功能涵盖所有图像使用案例;parseVideo()添加视频 - 隐形 PNGInfo 恢复: 回收被 NovelAI 和 seftth-pnginfo 扩展隐藏在像素 LSB 中的元数据, 即使图像主机剥去普通元数据
- 洛拉意识到: 列出应用于图像的 LORAs, 从 A1111 标记、 工具 JSON 和 ComfyUI 加载器节点读取
- 脚本原生类型: 写入 TypeScript, 包含完整类型定义
- 无依赖: 在节点和浏览器中工作, 没有任何外部依赖性
- 格式转换: 在 PNG 、 JPEG 和 WebP 之间无缝转换元数据
- 元数据保存: 转换格式时保留原始元数据结构(如PNG → JPEG → PNG 保存所有原始数据)
- AI 取证检测:识别商业AI服务(OpenAI,Google,xAI,Meta)通过C2PA,XMP或签名标记声明为自己的图像和视频——只检测,不验证签名
安装
npm install @enslo/sd-metadata
快速启动
import { parse } from '@enslo/sd-metadata';
// `imageBytes` is a Uint8Array or ArrayBuffer (from fs, fetch, a file input, ...)
const result = await parse(imageBytes);
if (result.status === 'success') {
console.log('Tool:', result.metadata.software); // 'novelai', 'comfyui', ...
console.log('Prompt:', result.metadata.prompt);
console.log('Size:', result.metadata.width, 'x', result.metadata.height);
}
见 使用量 用于Node.js、浏览器和用户标注入口,以及 高级示例 其他结果状况(vendor, (中文(简体) ), unrecognized, (中文(简体) ), empty, (中文(简体) ), invalid) (中文(简体) ).
工具支持
| 工具 | 巴布亚新几内亚 | JPEG 组合 | 网络P |
|---|---|---|---|
| 小说 * 联合国 | ✅ | 🔄️ | ✅ |
| 康菲乌伊 * 联合国 | ✅ | 🔄️ | ✅ |
| 稳定扩散网络UI | ✅ | ✅ | ✅ |
| 福尔吉 | ✅ | ✅ | ✅ |
| Forge 经典 | ✅ | ✅ | ✅ |
| 福尔格·尼欧 | ✅ | ✅ | ✅ |
| 重新定义 | ✅ | ✅ | ✅ |
| 轻松的Reforge | ✅ | ✅ | ✅ |
| (原始内容存档于2017-03-21). SD. 下一个 | ✅ | ✅ | ✅ |
| 印度 | ✅ | 🔄️ | 🔄️ |
| 沼泽地 * 联合国 | ✅ | ✅ | ✅ |
| 锡维泰 | ✅ | ✅ | ⚠️ |
| 日光艺术 | ✅ | 🔄️ | 🔄️ |
| 稳定矩阵 | ✅ | 🔄️ | 🔄️ |
| 拥抱 面相空间 | ✅ | 🔄️ | 🔄️ |
| 风云 | ✅ | ✅ | ✅ |
| 被破坏的福奥克 | ✅ | 🔄️ | 🔄️ |
| 容易扩散 | ✅ | ✅ | ✅ |
| 绘制事物 | ✅ | 🔄️ | 🔄️ |
| 德兹戈 | ✅ | ✅ | ✅ |
| 库斯阿特 | ✅ | 🔄️ | 🔄️ |
图例:
- ✅ 已完全支持 - 工具本身支持的格式,用样本文件验证
- 🔄️ 扩展支持 - 工具不本地支持的格式,但 sd-metadata 允许通过自定义格式转换来读取/写入。 支持回转转换为本地格式.
- ⚠️ 实验 - 通过分析参考代码或文件加以执行,未用实际样本文件加以核实。 可能无法正确提取所有元数据字段 .
扩展支持示例
- 稳定矩阵 (内在:只限PNG) → sd-元数据启用 JPEG/WebP 支持
- 小说 (原生:PNG, WebP) → sd-metadata 启用了 JPEG 支持
当从本地格式转换为扩展格式并返回(如PNG → JPEG → PNG)时,所有元数据都会被保存.
[注] * 有特定格式行为的工具——见下文.
[TIP] 帮助我们扩展工具支持! 我们正在积极收集实验组合(Civitai WebP)和无支持工具的样本图像. 如果您有这些或其他AI工具生成的样本图像,请考虑贡献! 见 捐款额 详细情况.
视频
parseVideo() 读取 MP4 / MOV (QuickTime)和 WebM / MKV (Matroska) 文件. 生成元数据通过和图像相同的解析器,所以将通常文本写入视频标签的工具被报告为相同 software。通过样本文件从:
- 康菲乌伊 ——内设
SaveVideo节点和 视频帮助套件是因为Video Combine(MP4、WebM、MKV;其ProRes MOV输出没有元数据) - 福尔格·尼欧 - Wan 2.2视频(MP4、MKV)
视频只读 : write() 财务报告和审定财务报表 embed() 拍摄图像。 见 视频文件。 。 。 .
格式 - 特定行为
一些工具在格式转换时有特定的行为:
- ComfyUI JPEG/网络P:读取支持多个节点格式(例如内置)
Save Animated WEBP财务报告和审定财务报表save-image-extended) (中文(简体) ). 写入总是匹配内置Save Animated WEBP节点Make编号 :ModelEXIF 标记为字节的字节- 布局 ComfyUI 本身为 WebP 拖放读取本地读取 – 放下除此之外的任何 PNG 块prompt编号 :workflow(例如:.parameters从第三方保存节点. - 小说网P:在"描述"字段中自动更正已腐败的UTF-8. WebP → PNG → WebP 往返生成有效,可读的元数据,但文字有小的校正.
- SWARMUI PNG JPEG/WebP: 原生 SwarmUI JPEG/WebP文件不包括节点信息. 在从PNG转换时,此库保存了 ComfyUI 工作流程
Make字段用于完整保存元数据(扩展支持).
使用量
[注] 所有例子都使用无害环境管理语法。 普通JS 用户可以替换
import与require数字 :const { parse } = require('@enslo/sd-metadata');
节点使用
import { parse, stringify } from '@enslo/sd-metadata';
import { readFileSync } from 'fs';
const imageData = readFileSync('image.png');
const result = await parse(imageData);
if (result.status === 'success') {
console.log('Tool:', result.metadata.software); // 'novelai', 'comfyui', etc.
console.log('Prompt:', result.metadata.prompt);
console.log('Model:', result.metadata.model?.name);
console.log('Size:', result.metadata.width, 'x', result.metadata.height);
}
// Format as human-readable text (works with any status)
const text = stringify(result);
if (text) {
console.log(text);
}
浏览器使用
import { parse, softwareLabels } from '@enslo/sd-metadata';
// Handle file input
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
if (!file) return;
const arrayBuffer = await file.arrayBuffer();
const result = await parse(arrayBuffer);
if (result.status === 'success') {
document.getElementById('tool').textContent = softwareLabels[result.metadata.software];
document.getElementById('prompt').textContent = result.metadata.prompt;
document.getElementById('model').textContent = result.metadata.model?.name || 'N/A';
}
});
用户标记使用
对于用户标注(Tampermonkey, violencemonkey等),通过IFE架构加载 @require数字 :
// ==UserScript==
// @name My Script
// @namespace https://example.com
// @require https://cdn.jsdelivr.net/npm/@enslo/[email protected]/dist/index.global.js
// ==/UserScript==
const response = await fetch(imageUrl);
const arrayBuffer = await response.arrayBuffer();
const result = await sdMetadata.parse(arrayBuffer);
if (result.status === 'success') {
console.log('Tool:', result.metadata.software);
console.log('Prompt:', result.metadata.prompt);
}
[TIP] 总是固定在特定的版本
@require为了稳定.
隐形 PNGInfo 恢复
小说(默认)和 隐形的 pnginfo 扩展家族(A1111/Forge, 康菲乌伊)将生成元数据的副本隐藏在像素最小的位点上,当图像主机剥去元数据块时,它在那里生存. parse() 自动恢复:当一个图像没有可读元数据时,它扫描像素作为回放,回收的结果带有 stealth: true. 宣布其供应商(ChatGPT或带有C2PA清单的双子座PNG)的图像没有扫描,因为这些服务不会写入隐形数据:
import { parse } from '@enslo/sd-metadata';
const result = await parse(strippedImage);
if (result.status === 'success') {
console.log(result.stealth); // true — recovered from pixels
console.log(result.metadata.prompt);
}
- 所有四个变体 被读取——α-或RGB-通道嵌入,被压缩或未被压缩——对于NovelAI的JSON有效载荷和扩展的纯信息有效载荷来说都是.
- 网络P: NovelAI在其无损失的WebP出口中也嵌入了被窃取的数据. 浏览器自动解码像素;在Node.js中,Bun或Deno通过解码器
decodePixels选项(例如由锐口支持),否则将跳过WebP扫描。 见下面的"服务器上的 Stealth recover" 高级示例。 。 。 . - 救援: 回收结果种子
write()不变,将原始工具的本地元数据恢复到已剥离的文件。 参见"检索剥去的元数据"下 高级示例。 。 。 . - 服务器:扫描膨胀并解开整幅图像(一台一相元像素PNG约50ms,4兆像素约200ms,在Node.js 24上). 解压被封顶在标题上,256个像素的米B和16个有效载荷的米B上,所以一个精心制作的文件不能声称是千兆字节,而是在未信任的上传上,在呼叫前限制文件大小和尺寸
parse(),或使用read()在不需要康复的地方. - 扫描需要
DecompressionStream(Node.js 18+, Bun 1.4+, Deno, 所有现代浏览器);没有它parse()降解为以块为基础的读取。 撰写隐形数据是故意超出范围.
视频文件
parseVideo() 从 MP4 / MOV 和 WebM / MKV 文件读取生成元数据,结果状态与 parse()通过 a Blob (浏览器) File,或节点 fs.openAsBlob()),并且只读取了持有元数据的字节范围,因此一个大文件从未被装入整个:
import { parseVideo, stringify } from '@enslo/sd-metadata';
import { openAsBlob } from 'node:fs';
const result = await parseVideo(await openAsBlob('output.mp4')); // or a File from an <input>
if (result.status === 'success') {
console.log(result.metadata.software); // 'comfyui', 'forge-neo', ...
console.log(result.metadata.prompt);
console.log(result.raw.format); // 'mp4' | 'mov' | 'webm' | 'mkv'
console.log(result.raw.tags); // the file's text tags, in file order
}
console.log(stringify(result)); // A1111-format text, as for images
商业服务(Google Veo、xAI Grok Imagine、Meta Muse、OpenAI Sora)的视频被报道 vendor 状态——见下面的"AI验证检测" 高级示例。不支持将元数据写入视频.
高级示例
格式转换
在不同图像格式之间转换元数据 :
import { parse, write } from '@enslo/sd-metadata';
// Read metadata from PNG
const pngData = readFileSync('comfyui-output.png');
const parseResult = await parse(pngData);
if (parseResult.status === 'success') {
// Convert PNG to JPEG (using your preferred image processing library)
const jpegImageData = convertToJpeg(pngData); // Pseudo-code: use sharp, canvas, etc.
// Embed the metadata into the JPEG
const result = write(jpegImageData, parseResult);
if (result.ok) {
writeFileSync('output.jpg', result.value);
console.log('Image converted to JPEG with metadata preserved');
}
}
提示 : 此库只处理读/写元数据 。 对于图像格式的实际转换(解码/编码像素),使用像图像处理库 锐口, (中文(简体) ), 竖起,或浏览器 Canvas API.
处理不同的结果类型
import { originLabel, parse } from '@enslo/sd-metadata';
const result = await parse(imageData);
switch (result.status) {
case 'success':
// Metadata successfully parsed
console.log(`Generated by ${result.metadata.software}`);
console.log(`Prompt: ${result.metadata.prompt}`);
break;
case 'vendor':
// A commercial AI service declared the image as its own — see "AI Provenance Detection" below
console.log(`Made by ${originLabel(result)} (unverified)`); // e.g. "xAI Grok Imagine"
break;
case 'unrecognized':
// Metadata exists but format is not recognized
console.log('Unknown metadata format');
// You can still access raw metadata for debugging:
console.log('Raw chunks:', result.raw);
break;
case 'empty':
// No metadata found
console.log('No metadata in this image');
break;
case 'invalid':
// Corrupted or invalid image data
console.log('Error:', result.message);
break;
}
处理未识别元数据
在使用不支持的工具处理元数据时:
import { parse, write } from '@enslo/sd-metadata';
const source = await parse(unknownImage);
// source.status === 'unrecognized'
// Write to target image
// - Same format (e.g., PNG → PNG): metadata preserved as-is
// - Cross-format (e.g., PNG → JPEG): metadata dropped with warning
const result = write(targetImage, source);
if (result.ok) {
saveFile('output.png', result.value);
if (result.warning) {
// Metadata was dropped during cross-format conversion
console.warn('Metadata was dropped:', result.warning.reason);
}
}
AI 鉴定(证人申报)
商业AI服务嵌入了一个他们制作图像的声明——一个签名的C2PA"Content Certification"清单,一个XMP包中的IPTC Digital SourceType,或者一个供应商自己的签名——而不是生成参数. parse() 财务报告和审定财务报表 parseVideo() 返回时 { status: 'vendor', info } 对于这些文件:
import { originLabel, parse, productLabel, vendorLabels } from '@enslo/sd-metadata';
const result = await parse(imageData);
if (result.status === 'vendor') {
console.log('Vendor:', vendorLabels[result.info.vendor]); // "OpenAI", "Google", "xAI", "Meta"
console.log('Service:', productLabel(result.info)); // "GPT Image", "Gemini", "Grok Imagine", "Muse"
console.log('Declared in:', result.info.source); // 'c2pa' | 'xmp' | 'signature'
console.log('As written:', result.info.product); // e.g. "ChatGPT", or undefined
console.log(originLabel(result)); // "xAI Grok Imagine" — the two joined
}
| 供应商 | 服务 | 声明 | 图像 | 视频 |
|---|---|---|---|---|
| 开放AI | GPT 图像 (ChatGPT), Sora | C2PA 数据 | 巴布亚新几内亚 | 马普4 |
| 谷歌 | 双子座,Veo | C2PA 数据 | 巴布亚新几内亚, JPEG | 马普4 |
| 页:1 大赦国际 | 格鲁克 想象一下 | C2PA, 签名 | JPEG 组合 | 马普4 |
| 元数据 | 缪斯 | XMP 电源 | JPEG, 网络程序 | 马普4 |
productLabel() 名称服务:已知产品值( )ChatGPT, (中文(简体) ), gpt-image,.)被映射到它的服务名上,一个没有一张的申报回落到卖家为媒体提供的主要服务(图片:GPT Image,双子座,Grok Imagine,Muse;视频:Sora,Veo,Grok Imagine,Muse). 所声明的数值保留在 info.product。 。 。 .
侦测只是证据. 没有签名,所以
vendor结果可以伪造,不能证明真实性。 这些标记也很容易被剥去(屏幕快照、重装、再编码),所以没有vendor结果不能证明图像是 没有 AI生成.
读取 LORAs
metadata.loras 列出影响图像的 LORAs, 按工具录入的顺序排列, 当没有时则缺席 :
import { parse } from '@enslo/sd-metadata';
const result = await parse(imageData);
if (result.status === 'success') {
for (const lora of result.metadata.loras ?? []) {
console.log(lora.name); // exactly as the tool wrote it: file stem, path, URN or display name
console.log(lora.weight); // UNet / model strength, when recorded
console.log(lora.clipWeight); // text-encoder strength, only when recorded separately
console.log(lora.hash); // as written (AutoV2, sha256, "blake3:..."), never normalized
}
}
名单来自 <lora:…> 标签和 Lora hashes 在A1111风格文本中,从LORA列出在他们的JSON(SwarmUI,InvokeAI,Foocus, Easy Difusion, Draw Tthings, TensorArt, Dezgo, KusArt,.)中写出的工具,从ComfyUI加载器节点中——只有采样器实际依赖的加载器,所以没有列出被绕过或未连接加载器.
服务器上的隐形回收( WebP)
PNG像素由库本身解码,但WebP解码取决于运行时间. 浏览器使用平台解码器( WebCodecs) ImageDecoder后退为 createImageBitmap + 键 OffscreenCanvas无配置。 在Node.js, Bun 或 Deno 中通过 decodePixels,例如由 锐口没有它,WebP隐形扫描被优雅地跳过:
import { parse } from '@enslo/sd-metadata';
import sharp from 'sharp';
const result = await parse(webpData, {
decodePixels: async (data) => {
const { data: pixels, info } = await sharp(data)
.ensureAlpha()
.raw()
.toBuffer({ resolveWithObject: true });
return { data: new Uint8Array(pixels), width: info.width, height: info.height };
},
});
检索剥去的元数据
隐藏结果种子 write() 直接将原始工具的本地元数据恢复到已剥离的文件——不需要单独的API :
import { parse, write } from '@enslo/sd-metadata';
const rescued = await parse(strippedImage);
if (rescued.status === 'success') {
const restored = write(strippedImage, rescued);
if (restored.ok) {
// restored.value now carries regular metadata again,
// readable by any tool — stealth data stays untouched in the pixels.
}
}
删除元数据
从图像中去除所有元数据 :
import { write } from '@enslo/sd-metadata';
const result = write(imageData, { status: 'empty' });
if (result.ok) {
writeFileSync('clean-image.png', result.value);
}
嵌入自定义元数据
以 A1111 格式创建并嵌入自定义元数据 :
import { embed } from '@enslo/sd-metadata';
const metadata = {
prompt: 'masterpiece, best quality, 1girl',
negativePrompt: 'lowres, bad quality',
width: 512,
height: 768,
sampling: {
steps: 20,
sampler: 'Euler a',
cfg: 7,
seed: '12345', // seeds are strings — some tools use 64-bit values
},
model: { name: 'model.safetensors' },
loras: [{ name: 'detail_tweaker', weight: 0.8 }], // written as <lora:detail_tweaker:0.8>
};
// Write to any image format (PNG, JPEG, WebP)
const result = embed(imageData, metadata);
if (result.ok) {
writeFileSync('output.png', result.value);
}
您还可以在设置行中添加任意的密钥值对 extras数字 :
const result = embed(imageData, {
...metadata,
extras: { Version: 'v1.10.0', 'Lora hashes': 'abc123' },
});
提示 : 如果一个额外的密钥匹配结构化字段( 例如, ),
Steps),外值在原位上超过结构值. 结尾处附上了新的密钥.
自兹 EmbedMetadata 是一个子集 GenerationMetadata 变量,您可以直接通过解析的元数据——包括小说AI及其 characterPrompts数字 :
import { parse, embed } from '@enslo/sd-metadata';
const result = await parse(novelaiPng);
if (result.status === 'success') {
// NovelAI metadata (or any other tool) works as-is
const output = embed(blankJpeg, result.metadata);
}
API 参考
parse(input: Uint8Array | ArrayBuffer, options?: ReadOptions): Promise<ParseResult>
读取并解析图像文件中的元数据 。 当一个图像没有可读的元数据时, 另外扫描像素以获取 Steather PNGInfo (参见 隐形 PNGInfo 恢复);扫描只在这样的情况下运行,而不是用于有供应商申报的图像,因此有普通元数据的图像不支付额外费用.
参数:
input- 图像文件数据(PNG、JPEG或WebP)options- 可选读取选项strict?: boolean(默认 :false——何时true,维度(width编号 :height)严格只取自元数据。 何时false,从图像头取出缺失的维度.decodePixels?: (data, format) => Promise<RgbaPixels | null>——解码WebP像素,用于平台无法进行隐形扫描的地方(服务器). 被称作"懒惰",只有在一个WebP没有可读元数据时才会使用. 见下面的"服务器上的 Stealth recover" 高级示例。 。 。 .
回返情况:
{ status: 'success', metadata, raw, stealth? }- 成功解析metadata: 统一元数据对象(见GenerationMetadata(中文(简体) )raw: 原始格式特定数据(圆柱/分集)stealth数字 :true当元数据从像素 LSB 中恢复时
{ status: 'vendor', info }- 一个商业AI服务(OpenAI,Google,xAI,Meta)宣布该图像为自己的;没有生成参数可读info数字 :VendorInfo—— 说vendor, (中文(简体) ),product(如有),source(单位:千美元)'c2pa' | 'xmp' | 'signature'和media: 'image'. 侦测只是——没有经过核实.
{ status: 'unrecognized', raw, stealth? }- 图像有元数据,但没有来自已知的AI工具raw: 保存供转换的原始元数据stealth数字 :true当原始数据从像素LSB中恢复时
{ status: 'empty' }- 在图像中找不到元数据{ status: 'invalid', message? }- 损坏或不支持的图像格式message: 可选错误描述
parseVideo(input: Uint8Array | ArrayBuffer | Blob, options?: VideoReadOptions): Promise<VideoParseResult>
从视频文件(MP4/MOV,WebM/MKV)读取并解析元数据. 见 视频文件。 。 。 .
参数:
input- 视频文件数据,或Blob编号 :FileA级Blob以小范围阅读,只读有元数据的框和元素,而不是装入全部.options- 可选读取选项strict?: boolean(默认 :false——何时true,维度严格取自元数据. 何时false,缺失的维度取自视频轨道.
回返情况:
状态与 parse(),与 VideoRawMetadata (单位:千美元)format 文件的文本 tags改为: RawMetadata 财务报告和审定财务报表 media: 'video' 在供应商中 info视频没有隐形数据,a VideoParseResult 无法传递到 write()。 。 。 .
read(input: Uint8Array | ArrayBuffer, options?: ReadOptions): ParseResult
[尖叫声] 折旧 ——使用
parse()换句话说.read()仍然可供需要同步、只读块的呼叫者使用,但无法恢复Steftth PNGInfo.
页:1 parse() 但它是同步的,从不扫描像素.
write(input: Uint8Array | ArrayBuffer, metadata: ParseResult): WriteResult
将元数据写入图像文件。 目标现有的元数据被替换,而不是合并:它的文本块, EXIF 和 XMP 是从 metadata,因此不结转诸如方向、日期时间或Make / Model等相机 EXIF.
参数:
input- 目标图像文件数据(PNG、JPEG或WebP)metadata- 说吧ParseResult从parse()status: 'success'或者说'empty'- 可以直接写作status: 'unrecognized'- 格式相同:写为-is;跨格式:删除带有警告的元数据- 被窃取的结果是可行的——写作恢复了原始工具的本土元数据(见"Rescuring extract medata"下 高级示例(中文(简体) )
回返情况:
{ ok: true, value: Uint8Array, warning?: WriteWarning }- 成功写入warning当部分或全部元数据被忽略时设置:reason实值'unrecognizedCrossFormat'(未确认元数据为另一种格式),'conversionEmpty'(工具的转换器找不到目标格式可以持有的任何东西)或'segmentTooLarge'(跳过一个超过65 535字节的JPEG COM/XMP段;message说吧
{ ok: false, error: { type, message? } }- 失败.type这是:'unsupportedFormat': 目标图像不是 PNG、 JPEG 或 WebP'conversionFailed': 元数据转换失败( 如不兼容格式)'writeFailed': 将元数据嵌入图像失败, 或者输入无法回写
embed(input: Uint8Array | ArrayBuffer, metadata: EmbedMetadata | GenerationMetadata): WriteResult
将自定义元数据嵌入到SD WebUI(A1111)格式的图像中. 一样 write(),将替换目标的现有元数据(文本块、EXIF、XMP).
参数:
input- 目标图像文件数据(PNG、JPEG或WebP)metadata- 说吧EmbedMetadata或者说GenerationMetadata嵌入( 使用)extras自定义设置字段)
回返情况:
{ ok: true, value: Uint8Array }- 成功写入(返回新图像数据){ ok: false, error: { type, message? } }- 失败.type这是:'unsupportedFormat': 目标图像不是 PNG、 JPEG 或 WebP'writeFailed': 将元数据嵌入图像失败
使用大小写 :
- 为程序生成的图像创建自定义元数据
- 将元数据从其他工具转换为WebUI兼容格式
- 构建输出WebUI可读元数据的应用程序
stringify(input: ParseResult | VideoParseResult | EmbedMetadata | GenerationMetadata): string
将元数据转换为人可读字符串.
参数:
input- 一个:ParseResult从parse()或者说VideoParseResult从parseVideo()——根据地位选择最佳代表性EmbedMetadata或者说GenerationMetadata— 格式为 A1111 文本
回返情况:
ParseResult编号 :VideoParseResult数字 :success+ A1111格式文本。 对于自己写出A1111文本的工具(sd-webui,Forge family, reForge,SD.Next,.),原始文本作为工具所写的返回,所以密钥库没有模型存活;对于其他工具,文本从元数据重建,LORAS包含vendor→<Vendor> <Service>(例如:.OpenAI GPT Image)),或当销售商身份不明时仅提供服务unrecognized+ 原始元数据为纯文本empty编号 :invalid— 空字符串
EmbedMetadata编号 :GenerationMetadata• A1111格式文本
使用大小写 :
- 在图像查看器或画廊中显示生成参数
- 将元数据复制到剪贴板, 作为可读文本
- 日志或调试已解析的元数据
- 预览
EmbedMetadata嵌入前
originLabel(input: ParseResult | VideoParseResult | GenerationMetadata | VendorInfo): string
在一个呼叫中显示所编文件的名称: 软件 success 结果(如 softwareLabels)),或供应商及其服务 vendor 结果(如 vendorLabels 财务报告和审定财务报表 productLabel(),当销售商身份不明时仅提供服务。 任何其他状态都给出了空字符串 。 元数据或供应商申报也可以自行传递.
import { originLabel, parse } from '@enslo/sd-metadata';
const result = await parse(imageData);
console.log(originLabel(result));
// => "NovelAI", "ComfyUI", "OpenAI GPT Image", "xAI Grok Imagine", ... or "" when there is nothing to name
softwareLabels: Record<GenerationSoftware, string>
仅读绘图 GenerationSoftware 其人可读的显示名称的标识符.
import { softwareLabels } from '@enslo/sd-metadata';
const result = await parse(imageData);
if (result.status === 'success') {
console.log(softwareLabels[result.metadata.software]);
// => "NovelAI", "ComfyUI", "Stable Diffusion WebUI", etc.
}
vendorLabels: Record<Vendor, string>
仅读绘图 Vendor 公司名称的标识符.
import { vendorLabels } from '@enslo/sd-metadata';
const result = await parse(imageData);
if (result.status === 'vendor') {
console.log(vendorLabels[result.info.vendor]);
// => "OpenAI", "Google", "xAI", "Meta", "Unknown"
}
productLabel(info: VendorInfo): string
显示制作供应商图像或视频的AI服务名称 。 已知的已申报产品(ChatGPT, (中文(简体) ), gpt-image, (中文(简体) ), Grok Imagine,.)被映射到其服务名;没有产品的声明回落到卖家为媒体提供的主要服务(图像:GPT Image,双子座,Grok Imagine,Muse;视频:Sora,Veo,Grok Imagine,Muse). 未知产品值按正文返回 .
import { productLabel, vendorLabels } from '@enslo/sd-metadata';
const result = await parse(imageData);
if (result.status === 'vendor') {
console.log(`${vendorLabels[result.info.vendor]} ${productLabel(result.info)}`);
// => "OpenAI GPT Image", "Google Gemini", "xAI Grok Imagine", "Meta Muse"
}
类型参考
本节概述主要类型. 完整类型定义见 文档类型。 。 。 .
ParseResult
产生的结果 parse() (已贬值) read()) 函数。 它使用受歧视的结合 status 字段. stealth 设置为 true 以 parse() 当结果从像素LSBs(Stealth PNGInfo)中恢复时.
type ParseResult =
| { status: 'success'; metadata: GenerationMetadata; raw: RawMetadata; stealth?: boolean }
| { status: 'vendor'; info: VendorInfo }
| { status: 'unrecognized'; raw: RawMetadata; stealth?: boolean }
| { status: 'empty' }
| { status: 'invalid'; message?: string };
VideoParseResult
结果是: parseVideo()状态相同. raw 保存容器格式和文件的文本标记,而不是块或块.
type VideoParseResult =
| { status: 'success'; metadata: GenerationMetadata; raw: VideoRawMetadata }
| { status: 'vendor'; info: VendorInfo }
| { status: 'unrecognized'; raw: VideoRawMetadata }
| { status: 'empty' }
| { status: 'invalid'; message?: string };
GenerationMetadata
返回的统一元数据结构 parse() 财务报告和审定财务报表 parseVideo() 由3个元数据类型组成的受歧视的联盟,以 software 字段 :
type GenerationMetadata =
| NovelAIMetadata // 'novelai' — adds V4 character-placement fields
| ComfyUIMetadata // 'comfyui' | 'tensorart' | 'stability-matrix' | 'swarmui' — adds the workflow graph (nodes)
| StandardMetadata; // 'sd-webui', 'forge', 'invokeai', 'dezgo', ... — baseline fields only
所有变体共用 BaseMetadata 字段 : prompt, (中文(简体) ), negativePrompt, (中文(简体) ), width, (中文(简体) ), height选择 model 编号 : sampling 编号 : hires 编号 : upscale 设置和 loras 列表中选择一个选项。 紧紧地紧紧地 software 使用特定工具领域的歧视者:
if (result.status === 'success') {
const metadata = result.metadata;
console.log('Prompt:', metadata.prompt);
console.log('Model:', metadata.model?.name);
console.log('Seed:', metadata.sampling?.seed); // a string
if (metadata.software === 'novelai') {
// TypeScript knows this is NovelAIMetadata
console.log('Character prompts:', metadata.characterPrompts);
}
}
对于每一种出口类型的完整定义,包括: BaseMetadata, (中文(简体) ), EmbedMetadata, (中文(简体) ), RawMetadata, (中文(简体) ), VendorInfo, (中文(简体) ), LoraSettings, (中文(简体) ), GenerationSoftware设置类型——参见 文档类型。 。 。 .
发展
见 贡献指南 (c) 发展结构和准则.
许可证
麻省理工学院