Как сделать текст PDF доступным для выбора с помощью Apache PDFBox?

Я пытаюсь сделать текст доступным для выбора в приложении для чтения PDF, созданном на JavaFX. У меня есть файлы PDF, содержащие скриншоты с текстом и слоем OCR. Поэтому мне нужно, чтобы текст можно было выбрать, как в обычном средстве просмотра. Я настроил получение изображения со страницы и теперь пытаюсь понять, как выделить текст.

Я пробовал следующее:

    InputStream is = this.getClass().getResourceAsStream(currentPdf);
    Image convertedImage;
    try {
        PDDocument document = PDDocument.load(is);
        List<PDPage> list = document.getDocumentCatalog().getAllPages();
        PDPage page = list.get(pageNum);
        List annotations = page.getAnnotations();
        PDAnnotationTextMarkup markup = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT);
        markup.setRectangle(new PDRectangle(600, 600));
        markup.setQuadPoints(new float[]{100, 100, 200, 100, 100, 500, 200, 500});
        annotations.add(markup);
        page.setAnnotations(annotations);
        BufferedImage image = page.convertToImage(BufferedImage.TYPE_INT_RGB, 128);
        convertedImage = SwingFXUtils.toFXImage(image, null);
        document.close();
        imageView.setImage(convertedImage);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

но это приводит к изображению без каких-либо бликов.

Я также пытался найти информацию о переполнении стека или других ресурсах, но ничего не нашел.

Был бы признателен за образец кода Java, который позволяет выделять текст с помощью мыши.


person Poliakoff    schedule 16.01.2016    source источник
comment
Загрузите PDF-файл.   -  person Tilman Hausherr    schedule 17.01.2016
comment
Вот пример bit.ly/1OWKAa1.   -  person Poliakoff    schedule 17.01.2016
comment
Хорошо, что там действительно есть текст. В PDFBox 2.0 есть инструмент DrawPrintTextLocations.java, попробуйте его. Ваш вопрос неясен, вам нужна программа просмотра с функцией пометки текста или вы хотите выделить что-то, а затем сохранить PDF?   -  person Tilman Hausherr    schedule 17.01.2016
comment
@TilmanHausherr Конечно, средство просмотра с функцией пометки текста: «Мне нужно, чтобы текст можно было выбрать, как в обычном средстве просмотра». В примере кода я пытаюсь сделать некоторый рабочий выбор текста во время выполнения, чтобы обернуть его позже в обработчик события щелчка мыши, который передаст координаты выбранной области методу, который выполняет выбор. Спасибо, проверим.   -  person Poliakoff    schedule 17.01.2016
comment
По сути, вы рисуете PDF-файл в растровое изображение (поэтому теряете всю информацию о том, какие пиксели являются текстом, а какие нет) и отображаете это изображение. Таким образом, вам нужно указать javafx, где находится текст.   -  person mkl    schedule 17.01.2016
comment
@Polyakoff также взгляните на пример ExtractTextByArea.java, это даст вам текст из выбранной области.   -  person Tilman Hausherr    schedule 17.01.2016


Ответы (1)


Я использовал ICEpdf и сделал следующее:

question.getSelectedBounds()
                .stream()
                .map(Shape::getBounds)
                .forEach(bounds -> {
                    SquareAnnotation squareAnnotation = (SquareAnnotation)
                            AnnotationFactory.buildAnnotation(
                                    pdfController.getPageTree().getLibrary(),
                                    Annotation.SUBTYPE_SQUARE,
                                    bounds);
                    squareAnnotation.setFillColor(true);
                    squareAnnotation.setFillColor(new Color(255, 250, 57, 120));
                    squareAnnotation.setRectangle(bounds);
                    squareAnnotation.setBBox(bounds);
                    squareAnnotation.resetAppearanceStream(null);
                    AbstractAnnotationComponent annotationComponent = AnnotationComponentFactory
                            .buildAnnotationComponent(squareAnnotation, pdfController.getDocumentViewController(),
                                    pageViewComponent, pdfController.getDocumentViewController().getDocumentViewModel());
                    pageViewComponent.addAnnotation(annotationComponent);
                });
person Poliakoff    schedule 22.01.2020