【问题标题】:How to get the font name of Text from a PDF?如何从 PDF 中获取 Text 的字体名称?
【发布时间】:2023-03-24 17:15:02
【问题描述】:

我希望提取 PDF 文件中文本的所有不同字体名称。我正在使用 iTextSharp DLL,下面给出的是我的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iTextSharp.text.pdf.parser;
using iTextSharp.text.pdf;

namespace GetFontName
{
    class Program
    {
        static void Main(string[] args)
        {
            PdfReader reader = new PdfReader("C:/Users/agnihotri/Downloads/Test.pdf");
            HashSet<String> names = new HashSet<string>();
            PdfDictionary resources;
            for (int p = 1; p <= reader.NumberOfPages; p++)
            {
                PdfDictionary dic = reader.GetPageN(p);
                resources = dic.GetAsDict(PdfName.RESOURCES);
                if (resources != null)
                {
                    //gets fonts dictionary
                    PdfDictionary fonts = resources.GetAsDict(PdfName.FONT);
                    if (fonts != null)
                    {

                        PdfDictionary font;

                        foreach (PdfName key in fonts.Keys)
                        {
                        font = fonts.GetAsDict(key);
                        string name = font.GetAsName(iTextSharp.text.pdf.PdfName.BASEFONT).ToString();

                            //check for prefix subsetted font

                        if (name.Length > 8 && name.ToCharArray()[7] == '+')
                        {
                        name = String.Format("%s subset (%s)", name.Substring(8), name.Substring(1, 7));

                        }
                        else
                        {
                                //get type of fully embedded fonts
                        name = name.Substring(1);
                        PdfDictionary desc = font.GetAsDict(PdfName.FONTDESCRIPTOR);
                        if (desc == null)
                        name += "no font descriptor";
                        else if (desc.Get(PdfName.FONTFILE) != null)
                        name += "(Type1) embedded";
                        else if (desc.Get(PdfName.FONTFILE2) != null)
                        name += "(TrueType) embedded ";
                        else if (desc.Get(PdfName.FONTFILE3) != null)
                        name += name;//("+font.GetASName(PdfName.SUBTYPE).ToString().SubSTring(1)+")embedded';
                        }

                        names.Add(name);
                        }
                    }
                }
            }
            var collections = from name in names
            select name;
            foreach (string fname in collections)
            {
            Console.WriteLine(fname);
            }
            Console.Read();

        }
    }
}

对于每个作为输入的 pdf 文件,我得到的输出是“Glyphless Font”no font descriptor”。输入文件的链接如下:

https://drive.google.com/open?id=0B6tD8gqVZtLiM3NYMmVVVllNcWc

【问题讨论】:

  • PdfReader reader = new PdfReader("C:/Users/agnihotri/Downloads/Test.pdf"); - 仔细检查文件的路径,这可能是问题,因为代码看起来没问题。如果尝试从互联网上复制粘贴的脚本以查看它们是否确实有效,我强烈建议添加一些调试。

标签: c# itextsharp


【解决方案1】:

我已经在 Adob​​e Acrobat 中打开了您的 PDF,并查看了字体面板。这是我看到的:

您有一个 LiberationMono 的嵌入子集,这意味着字体名称将作为 ABCDEF+LiberationMono 存储在文件中(其中 ABCDEF 是一系列 6 个随机但唯一的字符),因为该字体是子集。见What are the extra characters in the font name of my PDF?

现在让我们看看在 iText RUPS 中打开的同一个文件:

我们找到了/Font 对象,它有一个/FontDescriptor。在/FontDescriptor 中,我们以我们预期的格式找到/FontNameBAAAAA+LiberationMono

现在您知道在哪里可以找到该名称,您可以调整您的代码。

【讨论】:

  • 感谢您的澄清....请介意帮助我编写代码。我只是新手编码和 c#
  • @Rahul,不要在这么早的时候放弃!一旦你有这样有用的提示,请尝试应用它 - 这是非常好的做法。
  • 不确定我是否走对了......得到了提示:font.GetAsDict(PdfName.FontDescriptor.FontName); if (desc == null) name += "没有字体描述符"; else if (desc.Get(PdfName.FontName) != null) name += "(Type1) embedded"; else if (desc.Get(PdfName.FontName) != null) name += "(TrueType) embedded "; else if (desc.Get(PdfName.FontName) != null)
  • 请告诉我
【解决方案2】:

以最小的更改运行代码作为输出

%s subset (%s)

实际上%s 看起来像一个Java 格式字符串,而不是一个.Net 格式字符串。使用更多.Net'ish格式字符串{0} subset ({1})我得到

LiberationMono subset (BAAAAA+)

我建议您在文件路径中使用反斜杠和 @"..." 字符串形式而不是斜杠,例如像这样

PdfReader reader = new PdfReader(@"C:\Users\agnihotri\Downloads\Test.pdf");

并仔细检查文件名和路径 --- 在您提供的所有文件都命名为 Hello_World.pdf 之后。

【讨论】:

  • 感谢大家的建议和帮助。我已经能够通过对代码的任何更改来解决问题。唯一需要做的是使用 iTextSharp 5.5.9 dll,其余一切都很好。这可以标记为关闭
  • @RahulAgnihotri 唯一需要的是使用 iTextSharp 5.5.9 dll - 嗯,因为你没有提到你使用的版本,你给人的印象是你用过现在的当前版本一直... 这可以标记为已关闭 - 您可以自己做:创建一个包含原因的答案(类似于“使用旧 iTextSharp 版本,适用于当前 5.5.9")并将该答案标记为已接受(单击其左上角的勾号)。可能无法立即将自己的答案标记为已接受,但几小时后肯定可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-01
  • 2019-01-18
  • 2014-04-25
相关资源
最近更新 更多