Apache PDFBox: La confusión acerca de las coordenadas

Chris01:

Trato de extraer parte del texto de un PDF. Para que necesito para definir un rectángulo que contiene el texto.

Me reconocido que las coordenadas pueden tener un significado diferente cuando comparo las coordenadas de extracción de texto a coordenadas de dibujo.

package MyTest.MyTest;

import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.PDPageContentStream.*;
import org.apache.pdfbox.text.*;
import java.awt.*;
import java.io.*;

public class MyTest 
{   
  public static void main (String [] args) throws Exception
  { 
    PDDocument pd = PDDocument.load (new File ("my.pdf"));  
    PDFTextStripperByArea st = new PDFTextStripperByArea ();
    PDPage pg = pd.getPage (0);

    float h = pg.getMediaBox ().getHeight ();
    float w = pg.getMediaBox ().getWidth ();
    System.out.println (h + " x " + w + " in internal units");
    h = h / 72 * 2.54f * 10;
    w = w / 72 * 2.54f * 10;
    System.out.println (h + " x " + w + " in mm");



    int X = 85;
    int Y = 175;
    int dX = 250;
    int dY = 15;

    // extract some text
    st.addRegion ("a", new Rectangle (X, Y, dX, dY));
    st.extractRegions (pg);
    String text = st.getTextForRegion ("a");
    System.out.println("text="+text);


    // fill a rectangle
    PDPageContentStream contents = new PDPageContentStream (pd, pg,AppendMode.APPEND, false);
    contents.setNonStrokingColor (Color.RED);  
    contents.addRect (X, Y, dX, dY);
    contents.fill ();
    contents.close ();
    pd.save ("x.pdf");
  }
}

El extracto de texto I (salida de texto en la consola =) no es el texto que overdraw con mi rectángulo rojo (x.pdf generado).

¿¿Por qué??

Para la prueba de probar algunos PDF que ya tiene. Para evitar una gran cantidad de try / error en el objetivo de un rectángulo con texto en él uso un archivo con una gran cantidad de texto.

MKL:

Hay (al menos) dos cuestiones en su enfoque:

Diferentes sistemas de coordenadas

Utiliza st.addRegion. Su comentario JavaDoc nos dice:

/**
 * Add a new region to group text by.
 *
 * @param regionName The name of the region.
 * @param rect The rectangle area to retrieve the text from. The y-coordinates are java
 * coordinates (y == 0 is top), not PDF coordinates (y == 0 is bottom).
 */
public void addRegion( String regionName, Rectangle2D rect )

(En realidad, todo el aparato de extracción de texto de PDFBox utiliza su propio sistema de coordenadas, y ya ha habido muchas preguntas sobre desbordamiento de pila a causa de irritaciones que esto causó.)

Por otro lado contents.addRectno utiliza esas coordenadas "java". Por lo tanto, hay que restar la coordenada y se utiliza en la extracción de texto del cuadro de recorte máximo coordenada y para obtener una coordenada para addRect.

Por otra parte, los rectángulos región tienen su punto de anclaje en la parte superior izquierda, mientras que los rectángulos PDF regulares (como el que se define con contents.addRect) la tienen en la parte inferior izquierda. De este modo, además, se tiene que sumar o restar la altura del rectángulo de la coordenada y.

En realidad, puede que tenga que cambiar la coordenada x, también. No se refleja, pero puede haber un cambio, coordinar la extracción de texto PDFBox sistema utiliza x = 0 para el borde izquierdo de la página, pero eso no es necesariamente el caso en el espacio de usuario en PDF. Por lo tanto, es posible que tenga que añadir la izquierda x fronterizas de coordenadas de la casilla de recorte a su texto la extracción coordenada x.

Posiblemente cambiado sistema de coordenadas

En el contenido de la página corriente del sistema de coordenadas se puede haber cambiado mediante la aplicación de una transformación de la matriz de transformación actual. Como resultado las coordenadas en las instrucciones anexa a ella pueden tener un significado diferente que incluso esbozó anteriormente.

Para descartar tal efecto, se debe utilizar una diferente PDPageContentStreamconstructor con un adicional boolean resetContextde parámetros:

/**
 * Create a new PDPage content stream.
 *
 * @param document The document the page is part of.
 * @param sourcePage The page to write the contents to.
 * @param appendContent Indicates whether content will be overwritten, appended or prepended.
 * @param compress Tell if the content stream should compress the page contents.
 * @param resetContext Tell if the graphic context should be reset. This is only relevant when
 * the appendContent parameter is set to {@link AppendMode#APPEND}. You should use this when
 * appending to an existing stream, because the existing stream may have changed graphic
 * properties (e.g. scaling, rotation).
 * @throws IOException If there is an error writing to the page contents.
 */
public PDPageContentStream(PDDocument document, PDPage sourcePage, AppendMode appendContent,
                           boolean compress, boolean resetContext) throws IOException

es decir, sustituir

PDPageContentStream contents = new PDPageContentStream (pd, pg,AppendMode.APPEND, false);

por

PDPageContentStream contents = new PDPageContentStream (pd, pg,AppendMode.APPEND, false, false);

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=407386&siteId=1
Recomendado
Clasificación