簡體   English   中英

提取和打印文本位置

[英]Extracting and Printing text positions

我已經在pdfbox上進行了一些實驗,但目前仍停留在一個我懷疑與坐標系有關的問題上。
我正在擴展PDFTextStripper以獲取pdf頁面中每個字符的X和Y。
最初,我是用ImageIO創建一個Image的,它在接收到的位置打印文本,並在我想要的每個參考的底部都打上一個小標記(帶有不同顏色的矩形),一切似乎都很好。 但是現在為了避免從pdf中丟失樣式,我只想覆蓋pdf並添加以前的口語標記,但是我得到的坐標在PDPa​​geContentStream中不匹配。
從PDFTextStripper-> processTextPosition到視覺坐標的匹配pdf坐標的任何幫助

使用版本1.8.11

正如評論中所討論的,這是DrawPrintTextLocations工具的1.8版本,它是2.0版本的示例集合的一部分,並且基於更知名的PrintTextLocations示例。 與2.0版本不同,此版本不顯示字體邊界框,僅顯示文本提取大小,大約是一個小的字形(a,e等)的高度。 它用作文本提取的啟發式工具。 這就是“我得到的文本位置被弄成一半”效果的原因。 如果需要邊框,最好使用2.0(可能太大)。 要獲得准確的大小,您必須計算每個字形的路徑並獲取該字形的邊界,同樣,您需要該字形的2.0版本。

public class DrawPrintTextLocations extends PDFTextStripper
{
    private BufferedImage image;
    private final String filename;
    static final int SCALE = 4;
    private Graphics2D g2d;
    private final PDDocument document;

    /**
     * Instantiate a new PDFTextStripper object.
     *
     * @param document
     * @param filename
     * @throws IOException If there is an error loading the properties.
     */
    public DrawPrintTextLocations(PDDocument document, String filename) throws IOException
    {
        this.document = document;
        this.filename = filename;
    }

    /**
     * This will print the documents data.
     *
     * @param args The command line arguments.
     *
     * @throws IOException If there is an error parsing the document.
     */
    public static void main(String[] args) throws IOException
    {
        if (args.length != 1)
        {
            usage();
        }
        else
        {
            PDDocument document = null;
            try
            {
                document = PDDocument.load(new File(args[0]));

                DrawPrintTextLocations stripper = new DrawPrintTextLocations(document, args[0]);
                stripper.setSortByPosition(true);

                for (int page = 0; page < document.getNumberOfPages(); ++page)
                {
                    stripper.stripPage(page);
                }
            }
            finally
            {
                if (document != null)
                {
                    document.close();
                }
            }
        }
    }

    private void stripPage(int page) throws IOException
    {
        PDPage pdPage = (PDPage) document.getDocumentCatalog().getAllPages().get(page);
        image = pdPage.convertToImage(BufferedImage.TYPE_INT_RGB, 72 * SCALE);
        PDRectangle cropBox = pdPage.getCropBox();

        g2d = image.createGraphics();
        g2d.setStroke(new BasicStroke(0.1f));
        g2d.scale(SCALE, SCALE);

        setStartPage(page + 1);
        setEndPage(page + 1);

        Writer dummy = new OutputStreamWriter(new ByteArrayOutputStream());
        writeText(document, dummy);

        // beads in green
        g2d.setStroke(new BasicStroke(0.4f));
        List<PDThreadBead> pageArticles = pdPage.getThreadBeads();
        for (PDThreadBead bead : pageArticles)
        {
            PDRectangle r = bead.getRectangle();
            GeneralPath p = transform(r, Matrix.getTranslatingInstance(-cropBox.getLowerLeftX(), cropBox.getLowerLeftY()));
            AffineTransform flip = new AffineTransform();
            flip.translate(0, pdPage.findCropBox().getHeight());
            flip.scale(1, -1);
            Shape s = flip.createTransformedShape(p);
            g2d.setColor(Color.green);
            g2d.draw(s);
        }

        g2d.dispose();

        String imageFilename = filename;
        int pt = imageFilename.lastIndexOf('.');
        imageFilename = imageFilename.substring(0, pt) + "-marked-" + (page + 1) + ".png";
        ImageIO.write(image, "png", new File(imageFilename));
    }

    /**
     * Override the default functionality of PDFTextStripper.
     */
    @Override
    protected void writeString(String string, List<TextPosition> textPositions) throws IOException
    {
        for (TextPosition text : textPositions)
        {
            System.out.println("String[" + text.getXDirAdj() + ","
                    + text.getYDirAdj() + " fs=" + text.getFontSize() + " xscale="
                    + text.getXScale() + " height=" + text.getHeightDir() + " space="
                    + text.getWidthOfSpace() + " width="
                    + text.getWidthDirAdj() + "]" + text.getCharacter());

            // in red:
            // show rectangles with the "height" (not a real height, but used for text extraction 
            // heuristics, it is 1/2 of the bounding box height and starts at y=0)
            Rectangle2D.Float rect = new Rectangle2D.Float(
                    text.getXDirAdj(),
                    (text.getYDirAdj() - text.getHeightDir()),
                    text.getWidthDirAdj(),
                    text.getHeightDir());
            g2d.setColor(Color.red);
            g2d.draw(rect);
        }
    }

    /**
     * This will print the usage for this document.
     */
    private static void usage()
    {
        System.err.println("Usage: java " + DrawPrintTextLocations.class.getName() + " <input-pdf>");
    }


    /**
     * Transforms the given point by this matrix.
     *
     * @param x x-coordinate
     * @param y y-coordinate
     */
    private Point2D.Float transformPoint(Matrix m, float x, float y)
    {
        float[][] values = m.getValues();
        float a = values[0][0];
        float b = values[0][1];
        float c = values[1][0];
        float d = values[1][1];
        float e = values[2][0];
        float f = values[2][2];
        return new Point2D.Float(x * a + y * c + e, x * b + y * d + f);
    }

    /**
     * Returns a path which represents this rectangle having been transformed by the given matrix.
     * Note that the resulting path need not be rectangular.
     */
    private GeneralPath transform(PDRectangle r, Matrix matrix)
    {
        float x1 = r.getLowerLeftX();
        float y1 = r.getLowerLeftY();
        float x2 = r.getUpperRightX();
        float y2 = r.getUpperRightY();

        Point2D.Float p0 = transformPoint(matrix, x1, y1);
        Point2D.Float p1 = transformPoint(matrix, x2, y1);
        Point2D.Float p2 = transformPoint(matrix, x2, y2);
        Point2D.Float p3 = transformPoint(matrix, x1, y2);

        GeneralPath path = new GeneralPath();
        path.moveTo((float) p0.getX(), (float) p0.getY());
        path.lineTo((float) p1.getX(), (float) p1.getY());
        path.lineTo((float) p2.getX(), (float) p2.getY());
        path.lineTo((float) p3.getX(), (float) p3.getY());
        path.closePath();
        return path;
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM