2015-06-25 4 views
0

Я извлекаю текст из pdfs с iTextSharp в пределах определенных прямоугольников.Откорректируйте TextextSharp Text Extraction Newline Threshold

RenderFilter renderfilter = new RegionTextRenderFilter(pdfRect); 
ITextExtractionStrategy strategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), renderfilter); 
var text = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy); 

Некоторые из линий имеют текст, который изменяется в вертикальном выравнивании, так что я получаю новые строки, где не должно быть новой строки. Как я могу переопределить обнаружение новой строки, чтобы увеличить пороговое значение для обработки текста как находящегося на одной строке? Я посмотрел на метод SameLine, но не вижу, как я могу это использовать, даже если я переопределяю LocationTextExtractionStrategy или если это вообще необходимо сделать?

+1

Если отклонение в вертикальном выравнивании идет строго вниз, необходимо изменить 'SameLine'. Боюсь, однако, было бы проще всего скопировать всю «LocationTextExtractionStrategy» и манипулировать копией из-за многих частных членов. Если изменение также может быть в направлении вверх, вам также придется заменить вызов 'filtTextChunks.Sort()'. – mkl

+0

Спасибо за быстрый ответ. Можете ли вы рассказать об этом подробнее? Итак, SameLine вызывается для каждой буквы, чтобы узнать, находится ли она в одной строке? И тогда, что именно я должен был бы изменить в вызове Сортировка? – bzap16

+0

* SameLine вызывается для каждой буквы, чтобы определить, находится ли она в одной строке * - Нет, для каждого фрагмента. Но куски действительно могут состоять из отдельных букв (обычно, хотя они длиннее). – mkl

ответ

0

Я смог добиться того, что мне было нужно, реализовав ваши предложения. Я использую здесь «магическое» значение, и это, вероятно, должно быть связано с размерами глифов. Но пока это работает для меня. Я мог видеть параметризацию значения «5» при применении некоторых эвристик.

virtual public int CompareTo(TextChunk rhs) 
{ 
    if (this == rhs) return 0; // not really needed, but just in case 

    int rslt = 0; 
    rslt = CompareInts(orientationMagnitude, rhs.orientationMagnitude); 
    if (rslt != 0 && AbsoluteDifference(orientationMagnitude, rhs.orientationMagnitude) > 5) 
    return rslt; 


    rslt = CompareInts(distPerpendicular, rhs.distPerpendicular); 
    if (rslt != 0 && AbsoluteDifference(distPerpendicular, rhs.distPerpendicular) > 5) 
    return rslt; 

    // note: it's never safe to check floating point numbers for equality, and if two chunks 
    // are truly right on top of each other, which one comes first or second just doesn't matter 
    // so we arbitrarily choose this way. 
    rslt = distParallelStart < rhs.distParallelStart ? -1 : 1; 

    return rslt; 
} 

virtual public bool SameLine(TextChunk a) 
{ 
    if (orientationMagnitude != a.orientationMagnitude && AbsoluteDifference(orientationMagnitude, a.orientationMagnitude) > 5) return false; 
    if (distPerpendicular != a.distPerpendicular && AbsoluteDifference(distPerpendicular,a.distPerpendicular) > 5) return false; 
    return true; 
} 

public int AbsoluteDifference(int num1, int num2) 
{ 
    return Math.Abs(num1 - num2); 
} 
+0

Вы также можете изменить код в общедоступном виртуальном bool SameLine (ITextChunkLocation other) { return OrientationMagnitude == other.OrientationMagnitude && DistPerpendicular == other.DistPerpendicular; }, просто изменив равное условие на значение разницы, которое соответствует вашим потребностям. –