0

I am looking for a pdfminer analog for js or java. i need to parse a pdf file into text and get the coordinates of each sentence (x, y, width, height). it would also be nice if it could work not only with text but also with images

The best I could find is pdf2json, but it gives coordinates in a strange way, it is not clear how to work with them.

3
  • You are looking for a library, right? I am surprised by your JavaScript or Java requirement, as those are very different environments. Are you OK with command-line tools too?
    – Nicolas Raoul
    Nov 13, 2023 at 6:28
  • yes, i am looking a library. It's a work requirement. I'd just pick python and that's it, but I can't.
    – Maxim G
    Nov 13, 2023 at 12:09
  • Just being curious, do you want to integrate this library into an existing Java program? Or inside an existing JavaScript program?
    – Nicolas Raoul
    Nov 14, 2023 at 1:21

1 Answer 1

0

The PDF4Java library can extract the information you need from a PDF file. Sample code below shows how to extract the positions of text runs, glyphs and images.

import com.o2sol.pdf4java.PDFFixedDocument;
import com.o2sol.pdf4java.content.PDFContentExtractor;
import com.o2sol.pdf4java.content.images.PDFVisualImage;
import com.o2sol.pdf4java.content.images.PDFVisualImageCollection;
import com.o2sol.pdf4java.content.text.PDFTextRun;
import com.o2sol.pdf4java.content.text.PDFTextRunCollection;
import com.o2sol.pdf4java.core.exceptions.PDFException;
import com.o2sol.pdf4java.graphics.*;
import com.o2sol.pdf4java.graphics.colors.PDFRgbColor;
import com.o2sol.pdf4java.graphics.fonts.*;

import java.util.Random;

public class ContentExtraction {
    public static void main(String[] args) {
        try {
            // Load the input file.
            PDFFixedDocument document = new PDFFixedDocument("..\\..\\SupportFiles\\content.pdf");

            extractTextAndHighlight(document);

            extractTextAndHighlightGlyphs(document);

            extractImagesAndHighlight(document);

            // Compress the page graphic content.
            for (int i = 0; i < document.getPages().size(); i++)
            {
                document.getPage(i).getCanvas().compressAndClose();
            }

            document.save("ContentExtraction.pdf");

            System.out.println("PDF document has been saved with success");
        }
        catch (PDFException ex) {
            System.out.println("Error creating PDF file");
            System.out.println(ex.getMessage());
        }
    }

    private static void extractTextAndHighlight(PDFFixedDocument document) {
        PDFRgbColor penColor = new PDFRgbColor();
        PDFPen pen = new PDFPen(penColor, 0.5);
        Random rnd = new Random();

        PDFContentExtractor ce = new PDFContentExtractor(document.getPage(0));
        PDFTextRunCollection trc = ce.extractTextRuns();
        for (int i = 0; i < trc.size(); i++) {
            penColor.setR(rnd.nextInt(256));
            penColor.setG(rnd.nextInt(256));
            penColor.setB(rnd.nextInt(256));

            PDFPath boundingPath = new PDFPath();
            PDFPoint[] textRunCorners = trc.get(i).getCorners();
            boundingPath.startSubpath(textRunCorners[0].getX(), textRunCorners[0].getY());
            boundingPath.addLineTo(textRunCorners[1].getX(), textRunCorners[1].getY());
            boundingPath.addLineTo(textRunCorners[2].getX(), textRunCorners[2].getY());
            boundingPath.addLineTo(textRunCorners[3].getX(), textRunCorners[3].getY());
            boundingPath.closeSubpath();

            document.getPage(0).getCanvas().drawPath(pen, boundingPath);
        }
    }

    private static void extractTextAndHighlightGlyphs(PDFFixedDocument document) {
        PDFRgbColor penColor = new PDFRgbColor();
        PDFPen pen = new PDFPen(penColor, 0.5);
        Random rnd = new Random();
        byte[] rgb = new byte[3];

        PDFContentExtractor ce = new PDFContentExtractor(document.getPage(1));
        PDFTextRunCollection trc = ce.extractTextRuns();
        PDFTextRun tr = trc.get(1);
        for (int i = 0; i < tr.getGlyphs().size(); i++) {
            penColor.setR(rnd.nextInt(256));
            penColor.setG(rnd.nextInt(256));
            penColor.setB(rnd.nextInt(256));

            PDFPath boundingPath = new PDFPath();
            PDFPoint[] glyphCorners = tr.getGlyph(i).getGlyphCorners();
            boundingPath.startSubpath(glyphCorners[0].getX(), glyphCorners[0].getY());
            boundingPath.addLineTo(glyphCorners[1].getX(), glyphCorners[1].getY());
            boundingPath.addLineTo(glyphCorners[2].getX(), glyphCorners[2].getY());
            boundingPath.addLineTo(glyphCorners[3].getX(), glyphCorners[3].getY());
            boundingPath.closeSubpath();

            document.getPage(1).getCanvas().drawPath(pen, boundingPath);
        }
    }

    private static void extractImagesAndHighlight(PDFFixedDocument document) {
        PDFPen pen = new PDFPen(new PDFRgbColor(255, 0, 192), 0.5);
        PDFBrush brush = new PDFBrush(new PDFRgbColor(0, 0, 0));
        PDFStandardFont helvetica = new PDFStandardFont(PDFStandardFontFace.HELVETICA, 8);
        PDFStringAppearanceOptions sao = new PDFStringAppearanceOptions();
        sao.setBrush(brush);
        sao.setFont(helvetica);
        PDFStringLayoutOptions slo = new PDFStringLayoutOptions();
        slo.setWidth(1000);

        PDFContentExtractor ce = new PDFContentExtractor(document.getPage(2));
        PDFVisualImageCollection vic = ce.extractImages(false);
        for (int i = 0; i < vic.size(); i++) {
            PDFVisualImage vi = vic.get(i);

            PDFPoint[] imageCorners = vi.getImageCorners();
            PDFPath boundingPath = new PDFPath();
            boundingPath.startSubpath(imageCorners[0].getX(), imageCorners[0].getY());
            boundingPath.addLineTo(imageCorners[1].getX(), imageCorners[1].getY());
            boundingPath.addLineTo(imageCorners[2].getX(), imageCorners[2].getY());
            boundingPath.addLineTo(imageCorners[3].getX(), imageCorners[3].getY());
            boundingPath.closeSubpath();

            document.getPage(2).getCanvas().drawPath(pen, boundingPath);

            slo.setX(imageCorners[3].getX() + 1);
            slo.setY(imageCorners[3].getY() + 1);
            String imageProperties = String.format("Image ID: %s\nPixel width: %d pixels\nPixel height: %d pixels\n" +
                            "Display width: %f points\nDisplay height: %f points\nHorizonal Resolution: %f dpi\nVertical Resolution: %f dpi",
                    vi.getImageID(), vi.getWidth(), vi.getHeight(), vi.getDisplayWidth(), vi.getDisplayHeight(), vi.getDpiX(), vi.getDpiY());
            document.getPage(2).getCanvas().drawString(imageProperties, sao, slo);
        }
    }
}

This is the output of extractTextAndHighlight method: extract text runs and highlight

This is the output of extractTextAndHighlightGlyphs method: extract text and highlight glyphs

This is the output of extractImagesAndHighlight method: extract images and highlight

The PDFContentExtractor class has also support for extracting page text as string, extracting words or extracting text lines.
A note on extracting text runs: a text run represent the output of a showText PDF operator. In this particular test PDF file a text run corresponds to a line of text (this is why the text is highlighted line by line) but a text run can be a letter, a word, a partial word, a phrase or partial phrase (this depends on the library that generated the PDF file).

Disclaimer: I work for the company that develops the PDF4Java library.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.