2016-06-14 4 views
1

Я ищу, чтобы извлечь все различные названия шрифтов текста в файле PDF. Я использую iTextSharp DLL, а ниже - мой код.Как получить имя шрифта текста из PDF?

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(); 

     } 
    } 
} 

Выхода я получаю не «Glyphless шрифта» нет шрифта дескриптора»для каждого PDF-файла в качестве входных данных Ссылки для входного файла выглядит следующим образом:.

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

+0

PdfReader reader = новый PdfReader ("C: /Users/agnihotri/Downloads/Test.pdf"); - Дважды проверьте путь к файлу, это может быть проблемой, поскольку код выглядит нормально. также я бы настоятельно рекомендовал добавить некоторую отладку, если вы пытаетесь скопировать копии сценариев из Интернета, чтобы убедиться, что они действительно работают. –

ответ

2

Я открыл . ваш PDF в Adobe Acrobat и я смотрю на панели шрифта Это то, что я видел:

enter image description here

у вас есть встроенный Sub Набор LiberationMono, что означает, что имя шрифта будет храниться в файле как ABCDEF + LiberationMono (где ABCDEF представляет собой серию из 6 случайных, но уникальных символов), потому что шрифт является подмножеством. См What are the extra characters in the font name of my PDF?

Теперь давайте посмотрим на тот же файл был открыт в IText RUPS:

enter image description here

Мы находим /Font объект и имеет /FontDescriptor. В /FontDescriptor мы находим /FontName в ожидаемом формате: BAAAAA+LiberationMono.

Теперь, когда вы знаете, где искать это имя, вы можете адаптировать свой код.

+0

Спасибо за разъяснение .... не обращай внимания на меня с кодом. Я просто свежую кодировку bie и C# –

+0

@Rahul, не сдавайтесь на этом раннем этапе! Как только у вас появятся подсказки, такие полезные, как это, пожалуйста, попробуйте применить его - это очень хорошая практика. – halfer

+0

Не уверен, что я правая дорожка ...... как получил подсказку: \t font.GetAsDict (PdfName.FontDescriptor.FontName); if (desc == null) name + = "no font descriptor"; 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.

+0

Спасибо всем за предложения и помощь. Я смог решить проблему с любыми изменениями в коде. Единственное, что нужно было, это использование iTextSharp 5.5.9 dll и отдых все было в порядке. Это можно отметить как закрытое –

+0

@RahulAgnihotri * Единственное, что нужно было для использования iTextSharp 5.5.9 dll * - Hhmmm, так как вы не упоминали версию, которую вы использовали, вы дали впечатление, что вы использовали текущую версию все время ... * Это можно пометить как закрытое *. Вы можете сделать это самостоятельно: создайте ответ, содержащий причину (что-то вроде строки «используемая старая версия iTextSharp, отлично работает с текущим 5.5.9») и отметьте этот ответ как (нажмите на галочку в верхнем левом углу). Пометка собственного ответа как принятого может быть невозможна немедленно, но через несколько часов это, безусловно, есть. – mkl

Смежные вопросы