2011-01-21 3 views
0

мне нужно сделать извлечение текста низкого уровня с использованием PRTokeniserнечитаемый шрифт с помощью iTextSharp PRTokeniser

Для некоторых PDF файлов все в порядке, но для некоторых других я получаю пустые строки (или, скорее, строка составлена ​​пустые коробки или пустые персонажи).

Все такие файлы следуют схеме:

endobj 
7 0 obj 
<</BaseFont/RDZRPI+TimesNewRoman/FontDescriptor 8 0 R/Type/Font 
/FirstChar 1/LastChar 10/Widths[ 444 500 444 500 444 333 500 500 278 250] 
/Encoding 11 0 R/Subtype/TrueType>> 
endobj 
11 0 obj 
<</Type/Encoding/BaseEncoding/WinAnsiEncoding/Differences[ 
1/a/b/c/d/e/f/g/h/i/space]>> 
endobj 

Каждый символ в маркере stringvalue не является ASCII или ANSI код, а индекс массива разностей. Например, если у меня есть строка типа «abc», я бы получил 1,2,3. Тогда iTextSharp понимал бы такие коды, как коды ASCII, и отображал бы их как пустые квадратные квадраты или любой другой символ.

Поэтому я должен был бы получить массив подмножество: номер 1 «а», номер 2 «б» ...

Проблема заключается в том, что массив basefont.differences имеет только пустые значения, и поэтому я не знаю, как перестроить строку.

С другой стороны, стратегия.GetResultantText правильно обрабатывает содержимое страницы, но мне нужно гораздо больше деталей, и я использую PRTokeniser, хотя я застрял в этой проблеме с шрифтом.

Любые идеи?


В PDF потоки все так:

/FirstChar 1/LastChar 8/Widths[ 722 444 278 500 250 944 333 500] 
/Encoding 11 0 R/Subtype/TrueType>> 
endobj 
11 0 obj 
<</Type/Encoding/BaseEncoding/WinAnsiEncoding/Differences[ 
1/H/e/l/o/space/W/r/d]>> 

В этом случае есть только это предложение в формате PDF: Хеллоу Word. Поэтому массив символов будет:

 
1 H 
2 e 
3 l 
4 o 
5 space 
6 W 
7 r 
8 d 

Мне нужно найти такой массив, используя iTextSharp для того, чтобы расшифровать строку маркеров.

Благодаря

ответ

0

11 0 obj <> даже не действительный синтаксис PDF ... (или это?) Пустой словарь выглядит <<>>. Я подозреваю, что вам не хватает деталей или двух.

Запись кодировки должна быть словарем или строкой. Эрк! <> является допустимой пустой строкой. Такие строки являются байтами, закодированными как шестнадцатеричные значения ... < 0102030304050604070308> -> «Hello World» в вашем примере кодирования.

OTOH, запись кодирования может быть только именем или словарем (PdfName или PdfDictionary в iText-talk), поэтому даже если это действительно пустая шестнадцатеричная строка, она по-прежнему недействительна.

На данный момент, я думаю, вы можете с радостью принять Открытый исходный код и заглянуть под обложки по тому, что делает strategy.GetResultantText.

PS: Я думаю, вы злоупотребляете PRTokenizer. Использование в потоковой части потока контента является тонким и денди, но с его использованием для повторного анализа словарей, и это чистые накладные расходы. Эти объекты уже проанализированы и превращены в экземпляры PdfStream, PdfString, PdfDictionary и т. Д. ... с использованием PRTokenizer.

PdfDictionary fontDict = magicallyFindFontDict(); 
PdfObject encodingObj = fontDict.getAsDirectObject(PdfName.ENCODING); 
if (encodingObj == null) { //bail 
} else if (encodingObj.isName()) { 
    if (PdfName.WINANSIENCODING.equals(encodingObj)) { 
    ... 
    } else if (...) {}... 

} else if (encodingObj.isDictionary()) { 
    // details in 9.6.6 of ISO PDF Spec 
    ... 
} 
1

Спасибо Марку за Ваш ответ:

Вы очень правы. Поэтому я попытался заглянуть под обложки по какой стратегии. GetResultantText, как вы мне предложили, без особого успеха. Моя конечная цель - получить координаты каждого слова в файле PDF. Поэтому я попытался найти стратегию LocationTextExtractionStrategy, которая кажется разумной отправной точкой.

Я могу получить текст, сделанный красиво, но я не знаю, как получить координаты каждого слова или фрагмента. Мне нужно получить доступ к чему-то вроде массива locationalResult (если такой массив существует), но я не знаю, как это сделать.

Вот мой код (VB.net):

Public Sub ParseLocation(ByVal sourcePDF As String) 
    Dim reader As New iTextSharp.text.pdf.PdfReader(sourcePDF) 
    Dim parser As New iTextSharp.text.pdf.parser.PdfReaderContentParser(reader) 
    Dim strategy As parser.LocationTextExtractionStrategy 
    Dim sResult As String 

    For i As Integer = 1 To reader.NumberOfPages 
     strategy = parser.ProcessContent(i, New LocationTextExtractionStrategy) 
     sResult = strategy.GetResultantText 
     Debug.Print(iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, i, strategy)) 
     Debug.Print(sResult) 

     strategy = parser.ProcessContent(i, New LocationTextExtractionStrategy) 
     Debug.Print(strategy.GetResultantText()) 
    Next i 
End Sub 
+0

Это тоже не ответ (см моего комментария к вашему дополнительному «ответу» перечислена @ user584106 на этот вопрос), несмотря на upvote вы получили для этого. Пожалуйста, прочитайте мой комментарий к другому «ответу». Я не уменьшаю это из-за вашего нового статуса здесь, в SO, но вы должны лучше познакомиться с работой этого сайта, прежде чем потерять репутацию. :) –

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