You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中读取PNG文件元数据中的Stable Diffusion提示词

如何在C#中读取PNG文件元数据中的Stable Diffusion提示词

我明白你现在卡在哪了——用Bitmap类读取PNG里的Stable Diffusion提示词时,不管试0x0110还是其他ID,都找不到对应的元数据项对吧?我来帮你梳理下问题根源和解决办法。

首先,先看看你当前的代码:

using (var image = new Bitmap(imagePath))
{
    // Get the metadata property items
    var propertyItems = image.PropertyItems;
    // Find the Stable Diffusion prompt property
    var stableDiffusionPrompt = Array.Find(propertyItems, p => p.Id == 0x0110); // 0x0110 is the ID for the Stable Diffusion prompt property
    if (stableDiffusionPrompt != null)
    {
        string prompt = GetStringFromProperty(stableDiffusionPrompt);
        Debug.WriteLine($"Stable Diffusion Prompt: {prompt}");
    }
    else
    {
        Debug.WriteLine("Stable Diffusion Prompt not found in the image metadata.");
    }
}

问题出在哪?

Bitmap类的PropertyItems主要读取的是标准EXIF元数据,但Stable Diffusion生成的提示词大多不会存在这些标准字段里。像Automatic1111这类主流工具,会把提示词、采样步数、模型参数等信息存在PNG文件的自定义tEXt chunk里,而GDI+的Bitmap并不会解析这些自定义chunk。

解决办法:直接解析PNG的tEXt chunk

大多数Stable Diffusion工具会把提示词存在名为parameters的tEXt chunk中,我们可以直接读取PNG文件的结构来提取这个信息,不用依赖Bitmap类。

这里给你写了一个实用的方法:

using System.IO;
using System.Text;
using System.Linq;

public static string ReadStableDiffusionPromptFromPng(string imagePath)
{
    using (var fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
    using (var br = new BinaryReader(fs))
    {
        // 验证PNG文件头
        var pngHeader = br.ReadBytes(8);
        if (!pngHeader.SequenceEqual(new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }))
        {
            throw new InvalidDataException("输入文件不是有效的PNG格式");
        }

        while (fs.Position < fs.Length)
        {
            // 读取chunk长度(PNG用大端字节序)
            var lengthBytes = br.ReadBytes(4).Reverse().ToArray();
            int chunkLength = BitConverter.ToInt32(lengthBytes, 0);
            
            // 读取chunk类型
            string chunkType = Encoding.ASCII.GetString(br.ReadBytes(4));
            
            if (chunkType == "tEXt")
            {
                // 读取tEXt chunk的内容
                byte[] textData = br.ReadBytes(chunkLength);
                int nullSeparatorIndex = Array.IndexOf(textData, (byte)0);
                
                if (nullSeparatorIndex != -1)
                {
                    // 提取关键字和对应的内容
                    string keyword = Encoding.UTF8.GetString(textData, 0, nullSeparatorIndex);
                    if (keyword.Equals("parameters", StringComparison.OrdinalIgnoreCase))
                    {
                        string promptContent = Encoding.UTF8.GetString(textData, nullSeparatorIndex + 1, textData.Length - nullSeparatorIndex - 1);
                        return promptContent;
                    }
                }
            }
            else
            {
                // 跳过非tEXt类型的chunk数据和CRC校验位
                fs.Seek(chunkLength + 4, SeekOrigin.Current);
            }
        }
    }
    // 没找到对应chunk时返回null
    return null;
}

// 调用示例
var prompt = ReadStableDiffusionPromptFromPng(imagePath);
if (!string.IsNullOrEmpty(prompt))
{
    Debug.WriteLine($"Stable Diffusion Prompt: {prompt}");
}
else
{
    Debug.WriteLine("未在图片元数据中找到Stable Diffusion提示词");
}

额外说明

  • 如果你的图片是用其他工具生成的,可能需要调整关键字(比如有的工具会用prompt而不是parameters),可以根据实际情况修改代码里的判断条件。
  • 这个方法直接操作PNG文件流,不依赖GDI+的元数据解析,能更准确地提取Stable Diffusion的自定义信息。

备注:内容来源于stack exchange,提问作者Philip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 10:53:01