2015-09-26 2 views
3

Я работаю с pdf на иврите с диакритическими знаками. Я хочу извлечь все слова с помощью своих координат. Я попытался использовать ITextSharp и pdfClown, и они оба не дали мне то, что я хочу.Как я могу извлечь слова с координатами из pdf с помощью .net?

В pdfКогда в ITextSharp отсутствуют буквы \ chars. Я не получаю координаты слов.

Есть ли способ сделать это? (Я ищу свободного рамочный \ кода)

EDIT:

PDFClown Код:

File file = new File(PDFFilePath); 
    TextExtractor te = new TextExtractor(); 
    IDictionary<RectangleF?, IList<ITextString>> strs = te.Extract(file.Document.Pages[0].Contents); 

    List<string> correctText = new List<string>(); 
    foreach (var key in strs.Keys) 
    { 
     foreach (var value in strs[key]) 
     { 
      string reversedText = new string(value.Text.Reverse().ToArray()); 
      string cleanText = RemoveDiacritics(reversedText); 
      correctText.Add(cleanText); 
     } 
    } 
+0

Как вы не объяснили, как именно вы пытались использовать iTextSharp или PDFClown, сложно сказать, что вы сделали неправильно. – mkl

+0

Я добавил код для pdf clown. Что касается itextsharp, у меня нет кода ... но если вы знаете, как это сделать, скажите мне. –

+0

Это очень неудачно, ведь там, кажется, вы получили все слова, а не позиции, и это не сложно. В контексте pdfclown вы можете поделиться примером PDF и указать, какие буквы там отсутствуют? – mkl

ответ

1

Вы не показываете, как вы пытаетесь извлечь текст с помощью IText (Sharp). Я предполагаю, что вы после официальной документации и что ваш код выглядит следующим образом:

public string ExtractText(byte[] src) { 
    PdfReader reader = new PdfReader(src); 
    MyTextRenderListener listener = new MyTextRenderListener(); 
    PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener); 
    PdfDictionary pageDic = reader.GetPageN(1); 
    PdfDictionary resourcesDic = pageDic.GetAsDict(PdfName.RESOURCES); 
    processor.ProcessContent(
     ContentByteUtils.GetContentBytesForPage(reader, 1), resourcesDic); 
    return listener.Text.ToString(); 
} 

Если код не выглядит так, это объясняет уже объясняет, первое, что вы делаете неправильно.

В этом методе есть один класс, который не является частью iTextSharp: MyTextRenderListener. Это класс вы должны написать и что выглядит, например, так:

public class MyTextRenderListener : IRenderListener { 
    public StringBuilder Text { get; set; } 

    public MyTextRenderListener() { 
     Text = new StringBuilder(); 
    } 
    public void BeginTextBlock() { 
     Text.Append("<"); 
    } 
    public void EndTextBlock() { 
     Text.AppendLine(">"); 
    } 
    public void RenderImage(ImageRenderInfo renderInfo) { 
    } 
    public void RenderText(TextRenderInfo renderInfo) { 
     Text.Append("<"); 
     Text.Append(renderInfo.GetText()); 
     LineSegment segment = renderInfo.GetBaseline(); 
     Vector start = segment.GetStartPoint(); 
     Text.Append("| x="); 
     Text.Append(start[Vector.I1]); 
     Text.Append("; y="); 
     Text.Append(start[Vector.I2]); 
     Text.Append(">"); 
    }  
} 

При выполнении этого кода, и вы посмотрите, что внутри Text, вы заметите, что PDF документ не хранит слова , Вместо этого он хранит текстовые блоки. В нашем специальном IRenderListener мы указываем начало и конец текстовых блоков, используя < и >. Внутри этих текстовых блоков вы найдете текстовые фрагменты. Мы помечаем фрагменты текста следующим образом: <text snippet| x=36.0000; y=806.0000>, где значения x и y дают вам координату начала базовой линии (в отличие от положения восхождения и спуска). Вы также можете получить конечную позицию базовой линии (и восхождения/спуска).

Теперь, как вы отделяете слова от всего этого? Проблема с текстовыми фрагментами, которые вы получаете, заключается в том, что они не соответствуют словам. См. Например, этот файл: hello_reverse.pdf

Когда вы открываете его в Adobe Reader, вы читаете «Hello World Hello People». Надеюсь, вы найдете четыре слова в потоке контента, не так ли? На самом деле, это то, что вы найдете:

<> 
<<ld><Wor><llo><He>> 
<<Hello People>> 

Чтобы отогнать слова, «Мир» и «Hello» с первой строки, вам нужно сделать много Math. Вместо того, чтобы получить базовую линию объекта TextRenderInfo, возвращаемого в методе вашего приемника рендера RenderText(), вы должны использовать метод GetCharacterRenderInfos(). Это вернет список объектов TextRenderInfo, который даст вам больше информации о каждом символе (включая положение этих символов). Затем вам нужно составить слова из этих разных символов.

Это объясняется в ответе MKL на этот вопрос: Retrieve the respective coordinates of all words on the page with itextsharp

Мы сделали подобные проекты. Один из них описан здесь: https://www.youtube.com/watch?v=lZnbhnU4m3Y

Вам нужно будет сделать некоторую кодировку, чтобы все было правильно. Одно слово о PdfClown: ваш текст, вероятно, хранится как UNICODE в вашем PDF-файле.Чтобы получить правильные символы, парсеру необходимо изучить отображение глифов, хранящихся в шрифте, и соответствующий символ UNICODE. Если PdfClown не может этого сделать, это означает, что PdfClown не выполняет эту задачу правильно. PdfClown - проект одного человека, поэтому вам придется попросить разработчика исправить это (если у него есть время).

Как вы можете узнать из видео, iText может помочь вам, но iText - это компания с дочерними компаниями в США, Бельгии и Сингапуре. Это компания со многими сотрудниками и чтобы эта компания работала, нам нужно зарабатывать деньги (так мы платим нашим сотрудникам). Поэтому вы не должны ожидать, что мы поможем вам бесплатно. Конечно, вы можете понять это, так как вы тоже не захотите работать бесплатно, не так ли?

+0

Что делать, если есть два символа с буквами с одинаковыми координатами? Стартовая позиция - то же самое. –

+0

Эти персонажи лишены возможности лигатуры? Также: каждый символ имеет такие показатели, как «предварительный» и «ограничивающий прямоугольник». Эти показатели могут также играть важную роль. –

+0

Я так думаю (лигатуры), почему ты спрашиваешь? ограничивающая рамка одинакова, и я не мог записать «продвижение» (просто чтобы напомнить, что я работаю с .net C#) –

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