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

如何使用PDFsharp提取PDF中已绘制矩形的颜色信息

如何使用PDFsharp提取PDF中已绘制矩形的颜色信息

嘿,我完全懂你的需求——你用PDFsharp在PDF页面角落画了个带唯一颜色的小矩形做标记,现在想重新打开文件读取这个颜色对吧?咱们来一步步解决这个问题。

首先得说清楚为什么你之前找/XObject没结果:你用XGraphics.DrawRectangle绘制的矩形,并不是作为独立的XObject存储的,而是直接被转换成了PDF页面内容流里的一系列绘图指令,所以在页面的Resources字典里找不到对应的条目。

接下来给你两种解决方案,按需选择:

方案一:生成PDF时记录颜色元数据(最简单)

如果你能控制PDF的生成过程,那直接在绘制矩形后给页面添加自定义元数据是最省心的办法,完全不用解析复杂的内容流:

绘制时添加元数据

// 你的绘制代码
var brush = new XSolidBrush(XColor.FromArgb(255, colorArray.R, colorArray.G, colorArray.B));
XGraphics gfx = XGraphics.FromPdfPage(document.Pages[0]);
gfx.DrawRectangle(brush, xRect);

// 添加自定义元数据,记录矩形颜色
PdfPage page = document.Pages[0];
page.Elements.Add("/MyMarkerColor", new PdfString($"RGB({colorArray.R},{colorArray.G},{colorArray.B})"));

读取时获取颜色

PdfDocument document = PdfReader.Open("your-file.pdf");
PdfPage page = document.Pages[0];

// 读取自定义元数据
PdfString colorEntry = page.Elements.GetValue("/MyMarkerColor") as PdfString;
if (colorEntry != null)
{
    string colorStr = colorEntry.Value;
    // 解析字符串得到RGB值,比如按逗号分割
    string[] rgbParts = colorStr.Replace("RGB(", "").Replace(")", "").Split(',');
    if (rgbParts.Length == 3 &&
        int.TryParse(rgbParts[0], out int r) &&
        int.TryParse(rgbParts[1], out int g) &&
        int.TryParse(rgbParts[2], out int b))
    {
        Console.WriteLine($"标记矩形颜色: RGB({r}, {g}, {b})");
    }
}

方案二:解析页面内容流提取颜色(适用于无法修改生成逻辑的情况)

如果没法在生成时加元数据,那就得直接解析PDF页面的内容流,提取绘图指令里的颜色信息。PDFsharp没有提供现成的高级解析API,所以需要手动处理:

步骤1:获取页面内容流

PdfDocument document = PdfReader.Open("your-file.pdf");
PdfPage page = document.Pages[0];

// 获取扁平化后的内容流字节
byte[] contentBytes = page.Contents.Flatten();
string content = Encoding.ASCII.GetString(contentBytes);

步骤2:解析颜色指令

你用XSolidBrush填充矩形,对应的PDF指令会是:先通过rg指令设置填充颜色(格式为r g b rg,其中r/g/b是0-1之间的归一化值),然后用re定义矩形路径,最后用f执行填充。

我们可以遍历内容流的指令,找到对应的颜色值:

string[] tokens = content.Split(new[] {' ', '\n', '\r'}, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < tokens.Length; i++)
{
    // 寻找填充颜色指令 "rg"
    if (tokens[i] == "rg" && i >= 3)
    {
        // 尝试解析前三个token为RGB归一化值
        if (double.TryParse(tokens[i-3], out double normR) &&
            double.TryParse(tokens[i-2], out double normG) &&
            double.TryParse(tokens[i-1], out double normB))
        {
            // 转换为0-255的RGB值
            int r = (int)Math.Round(normR * 255);
            int g = (int)Math.Round(normG * 255);
            int b = (int)Math.Round(normB * 255);
            
            // 如果你知道矩形在角落,可以结合坐标指令进一步筛选,比如找附近的位置参数
            Console.WriteLine("找到填充颜色: RGB({0}, {1}, {2})", r, g, b);
        }
    }
}

注意事项

  • 内容流里可能有多个rg指令,所以你需要结合矩形的位置(比如你知道标记在页面角落,可以找对应坐标附近的颜色指令)来确认哪个是你要的颜色。
  • PDF的坐标系统和PDFsharp的可能有差异,需要注意坐标转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:00:27