C# 如何从PDF中获取文本的字体名称?

C# 如何从PDF中获取文本的字体名称?,c#,itextsharp,C#,Itextsharp,我期待着提取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 GetFontNa

我期待着提取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文件的无字形字体,没有字体描述符作为输入。输入文件的链接如下所示:


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

您有一个LiberationMono的嵌入式子集,这意味着字体的名称将以ABCDEF+LiberationMono的形式存储在文件中,其中ABCDEF是一系列6个随机但唯一的字符,因为字体是subsetter。看

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

我们找到/Font对象,它有一个/FontDescriptor。在/FontDescriptor中,我们找到了我们期望的格式的/FontName:BAAAAA+LiberationMono


现在您知道了在哪里查找该名称,您可以修改代码。

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

您有一个LiberationMono的嵌入式子集,这意味着字体的名称将以ABCDEF+LiberationMono的形式存储在文件中,其中ABCDEF是一系列6个随机但唯一的字符,因为字体是subsetter。看

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

我们找到/Font对象,它有一个/FontDescriptor。在/FontDescriptor中,我们找到了我们期望的格式的/FontName:BAAAAA+LiberationMono


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

运行代码时,只需对输出进行最小的更改

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

我建议你用反斜杠和。。。字符串形式,而不是文件路径中的斜杠,例如

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

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

运行您的代码时,只需对输出进行最小的更改

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

我建议你用反斜杠和。。。字符串形式,而不是文件路径中的斜杠,例如

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

并在您提供的所有文件名为Hello_World.pdf后再次检查文件名和路径。

PdfReader reader=new PdfReaderC:/Users/agnihotri/Downloads/Test.pdf;-仔细检查文件的路径,这可能是问题所在,因为代码似乎没有问题。另外,如果尝试从internet复制粘贴的脚本以查看它们是否实际工作,我强烈建议添加一些调试。PdfReader reader=new PdfReaderC:/Users/agnihotri/Downloads/Test.pdf;-仔细检查文件的路径,这可能是问题所在,因为代码似乎没有问题。另外,如果尝试从internet复制粘贴的脚本,我强烈建议添加一些调试,以查看它们是否实际工作。感谢您的澄清…请介意帮助我编写代码。我只是个新手c@Rahul,不要在这个紧要关头放弃!一旦你有了这样有用的提示,请尝试应用它-这是一个很好的实践。不确定我是否正确……因为我得到了提示:font.GetAsDictPdfName.FontDescriptor.FontName;如果desc==空名称+=无字体描述符;如果desc.GetPdfName.FontName!=空名称+=嵌入的类型1;如果desc.GetPdfName.FontName!=空名称+=嵌入的TrueType;如果desc.GetPdfName.FontName!=请让我知道谢谢你的澄清…请帮我写代码。我只是个新手c@Rahul,不要在这个紧要关头放弃!一旦你有了这样有用的提示,请尝试应用它-这是一个很好的实践。不确定我是否正确……因为我得到了提示:font.GetAsDictPdfName.FontDescriptor.FontName;如果desc==空名称+=无字体描述符;如果desc.GetPdfName.FontName!=空名称+=嵌入的类型1;如果desc.GetPdfName.FontName!=空名称+=嵌入的TrueType;如果desc.GetPdfName.FontName!=请让我知道谢谢大家的建议和帮助。我已经能够通过对代码的任何更改来解决这个问题。唯一需要做的就是使用iTextSharp 5.5.9 dll和rest,一切正常。这可以标记为closed@RahulAgnihotri唯一需要做的是使用iTextSharp 5.5.9 dll-Hhmmm,因为您没有提到您使用的版本,您给人的印象是您一直在使用现在的版本。。。这可以标记为关闭-您可以自己完成:创建一个答案,其中包含原因,与使用的旧iTextSharp版本类似,在当前的5.5.9中运行良好,并将该答案标记为已接受,单击左上角的勾号。将自己的答案标记为接受
ed可能不会马上完成,但几个小时后肯定可以。谢谢大家的建议和帮助。我已经能够通过对代码的任何更改来解决这个问题。唯一需要做的就是使用iTextSharp 5.5.9 dll和rest,一切正常。这可以标记为closed@RahulAgnihotri唯一需要做的是使用iTextSharp 5.5.9 dll-Hhmmm,因为您没有提到您使用的版本,您给人的印象是您一直在使用现在的版本。。。这可以标记为关闭-您可以自己完成:创建一个答案,其中包含原因,与使用的旧iTextSharp版本类似,在当前的5.5.9中运行良好,并将该答案标记为已接受,单击左上角的勾号。将自己的答案标记为已接受可能无法立即实现,但几小时后肯定可以。