2012-08-10 38 views
8

Necesito analizar un documento PDF. Ya implementé el analizador y usé la biblioteca iText y hasta ahora funcionó sin ningún problema.Espacios en blanco extraños al analizar un PDF

Pero no, necesito analizar otro documento que obtiene espacios en blanco muy extraños en el medio de las palabras. Como ejemplo me sale:

Vo rber Zeitung auf die Motorr adsaison. Viele Motorr ADF er Ahr

Todas las palabras en negrita deben estar conectados, pero de alguna manera el analizador PDF es la adición de espacios en blanco en las palabras. Pero cuando copio y pego el contenido del PDF en un archivo de texto, no obtengo estos espacios.

Primero pensé que era por la biblioteca de análisis de PDF que estoy usando, pero también con otra biblioteca obtengo exactamente el mismo problema.

He echado un vistazo al singleSpaceWidth de las palabras analizadas y noté que siempre está variando cuando agrega un espacio en blanco. Traté de ponerlos juntos manualmente. Pero dado que no existe realmente un patrón para recombinar las palabras, es casi imposible.

¿Alguien más tiene un problema similar o incluso una solución a ese problema?

Conforme a lo solicitado, aquí tienes más información:

Analizar con SemTextExtractionStrategy:

PdfReader reader = new PdfReader("data/SpecialTests/SuedostSchweiz/" + src); 

SemTextExtractionStrategy semTextExtractionStrategy = new SemTextExtractionStrategy(); 

for (int i = 1; i <= reader.getNumberOfPages(); i++) { 
    // Set the page number on the strategy. Is used in the Parsing strategies. 
    semTextExtractionStrategy.pageNumber = i; 

    // Parse text from page 
    PdfTextExtractor.getTextFromPage(reader, i, semTextExtractionStrategy); 
} 

Aquí el método SemTextExtractionStrategy que en realidad analiza el t ext. Hay que añadir manualmente después de cada palabra analizada un espacio en blanco, pero de alguna manera lo hace dividir las palabras en la detección:

@Override 
public void parseText(TextRenderInfo renderInfo, int pageNumber) {  

    this.pageNumber = pageNumber; 

    String text = renderInfo.getText(); 

    currTextBlock.getText().append(text + " "); 

    .... 
} 

Aquí está toda la Clase SemTextExtraction pero allí lo hace solamente llamo el método de arriba (parseText):

public class SemTextExtractionStrategy implements TextExtractionStrategy { 

    // Text Extraction Strategies 
    public ColumnDetecter columnDetecter = new ColumnDetecter(); 

    // Image Extraction Strategies 
    public ImageRetriever imageRetriever = new ImageRetriever(); 

    public int pageNumber = -1; 

    public ArrayList<TextParsingStrategy> textParsingStrategies = new ArrayList<TextParsingStrategy>(); 
    public ArrayList<ImageParsingStrategy> imageParsingStrategies = new ArrayList<ImageParsingStrategy>(); 

    public SemTextExtractionStrategy() { 

     // Add all text parsing strategies which are later on applied on the extracted text 
     // textParsingStrategies.add(fontSizeMatcher); 
     textParsingStrategies.add(columnDetecter); 

     // Add all image parsing strategies which are later on applied on the extracted text 
     imageParsingStrategies.add(imageRetriever); 
    } 

    @Override 
    public void beginTextBlock() { 

    } 

    @Override 
    public void renderText(TextRenderInfo renderInfo) { 
     // TEXT PARSING 
     for(TextParsingStrategy strategy : textParsingStrategies) { 
      strategy.parseText(renderInfo, pageNumber); 
     } 
    } 

    @Override 
    public void endTextBlock() { 

    } 

    @Override 
    public void renderImage(ImageRenderInfo renderInfo) { 
     for(ImageParsingStrategy strategy : imageParsingStrategies) { 
      strategy.parseImage(renderInfo); 
     } 
    } 
} 
+0

indique la versión de iText que está utilizando y, de alguna manera, también debe proporcionar el PDF y el código con el que realiza el análisis. – Eugene

+0

Se agregó toda la información en la publicación anterior. – Prine

+0

¿qué pasa con la clase TextExtractionStrategy que utiliza? – Eugene

Respuesta

2

he procesado el archivo PDF dada con el Ghostscript siguiente comando:

gs -o out.pdf -q -sDEVICE=pdfwrite -dOptimize=false -dUseFlageCompression=false -dCompressPages=false -dCompressFonts=false whitespacesProblem.pdf 

Este comando crea un archivo out.pdf, que no tiene las codificaciones de flujo, por lo que es mejor legible. La parte interesante es en la línea 52, que he dividido en varias líneas para facilitar la lectura:

[ 
    (&;&)-287.988 
    (672744)29.9906 
    (+\(%)30.01 
    (+!4)29.9876 
    (&4)-287.989 
    (%4)30.0039 
    (&1&8)-287.975 
    (3=\)!)-288.021 
    (*&4)30.0212 
    (&=23)-287.996 
    (+1%)-287.99 
    (\(=&)-288.011 
    (8&1&)-287.974 
    (672744)29.9906 
    (+\(3+=378$)-250.977 
    (#7\)!) 
]TJ 

Entre los paréntesis son los caracteres de texto. Cambié algunos de ellos y observé el archivo PDF renderizado para ver qué personaje representa qué glifo. Luego descodifiqué el texto:

[ 
    (ele)-287.988 
    (Motorr)29.9906 *** 
    (adf)30.01 *** 
    (ahr)29.9876 *** 
    (er)-287.989 
    (fr)30.0039 
    (euen)-287.975 
    (sich)-288.021 
    ... 
] 

De hecho, hay espacio en blanco entre los caracteres. En su caso, este es probablemente el interletraje de la fuente. La pregunta ahora es cómo su biblioteca PDF interpreta este espacio en blanco, y me parece que incluso el "espacio en blanco negativo" se representa en un espacio en la cadena resultante.

+0

¿Hay alguna manera de deshacerse de esto o de una implementación? – NinjaOnSafari

+0

y qué herramienta has usado para generar el pdf? – NinjaOnSafari

+0

Es Ghostscript; He editado la respuesta para dejarlo en claro. Gracias por la pista. –

0

Debido a que el documento que usted tiene se divide en columnas, el error obvio es el interior de la

SemTextExtractionStrategy

clase. Supongo que la clase ColumnDetecter es probablemente la culpable y no iText. Solo puedo suponer que se implementa en función del tamaño de la columna, y luego recupero el texto en función de eso.

Si solo desea el texto, la implementación podría ser más simple, según el tamaño de la columna.

+0

Gracias por su respuesta. Definitivamente echaré un vistazo al ColumnDetecter. Pero el método parseText es de esta clase y allí obtengo el resultado directamente de la biblioteca iText donde las palabras ya están divididas. – Prine

1

Los espacios en blanco en pdf son un problema conocido como describe la respuesta aquí por Roland y también se observa en el primer comentario de https://issues.apache.org/jira/browse/TIKA-724

La respuesta que también trabajó para mí es la que se ve por huuhungus en https://github.com/smalot/pdfparser/issues/72

que es específico para PDFParser y que es cambiar el código que realmente añade este espacio extra a la PDFParser si usted sabe que va a tener este problema:

sr c/Smalot/PdfParser/Object.php a comentar la línea

$text .= ' '; 

no soluciona por completo, pero es al aceptables

Otras bibliotecas también pueden tener arreglos temporales similares para que pudieran ayudar con este problema en algunos casos.

+0

iText 5.2.1 es una versión antigua ahora. Las versiones actuales tienen propiedades/métodos reemplazables para ajustar en qué situaciones iText agrega un espacio y en cuáles no. Nunca agregar un espacio es, en general, una mala elección, muchos PDF se extraen con muy poco espacio. – mkl

Cuestiones relacionadas