pdf clown- не выделяет конкретное ключевое слово для поиска

Я использую pdf-clown с pdfclown-0.2.0-HEAD.jar. Я написал ниже код для выделения поиска по ключевому слову в pdf-файле на китайском языке, и тот же код отлично работает с pdf-файлом на английском языке.

import java.awt.Color;
import java.awt.Desktop;
import java.awt.geom.Rectangle2D;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.BufferedInputStream;
import java.io.File;
import org.pdfclown.documents.Page;
import org.pdfclown.documents.contents.ITextString;
import org.pdfclown.documents.contents.TextChar;
import org.pdfclown.documents.contents.colorSpaces.DeviceRGBColor;
import org.pdfclown.documents.interaction.annotations.TextMarkup;
import org.pdfclown.documents.interaction.annotations.TextMarkup.MarkupTypeEnum;

import org.pdfclown.files.SerializationModeEnum;
import org.pdfclown.util.math.Interval;
import org.pdfclown.util.math.geom.Quad;
import org.pdfclown.tools.TextExtractor;

public class pdfclown2 {
    private static int count;

    public static void main(String[] args) throws IOException {

        highlight("ebook.pdf","C:\\Users\\Downloads\\6.pdf");
        System.out.println("OK");
    }
    private static void highlight(String inputPath, String outputPath) throws IOException {

        URL url = new URL(inputPath);
        InputStream in = new BufferedInputStream(url.openStream());
        org.pdfclown.files.File file = null;

        try {
            file = new org.pdfclown.files.File("C:\\Users\\Desktop\\pdf\\test123.pdf");

        Map<String, String> m = new HashMap<String, String>();
            m.put("亿元或","hi");
            m.put("收入亿来","hi");



        System.out.println("map size"+m.size());
         long startTime = System.currentTimeMillis();




            // 2. Iterating through the document pages...
            TextExtractor textExtractor = new TextExtractor(true, true);
            for (final Page page : file.getDocument().getPages()) {
                Map<Rectangle2D, List<ITextString>> textStrings = textExtractor.extract(page);
                for (Map.Entry<String, String> entry : m.entrySet()) {

                    Pattern pattern;
                    String serachKey =  entry.getKey();
                    final String translationKeyword = entry.getValue();
                /*
                        if ((serachKey.contains(")") && serachKey.contains("("))
                                || (serachKey.contains("(") && !serachKey.contains(")"))
                                || (serachKey.contains(")") && !serachKey.contains("(")) || serachKey.contains("?")
                                || serachKey.contains("*") || serachKey.contains("+")) {s
                            pattern = Pattern.compile(Pattern.quote(serachKey), Pattern.CASE_INSENSITIVE);
                        }
                        else*/
                             pattern = Pattern.compile(serachKey, Pattern.CASE_INSENSITIVE);
                // 2.1. Extract the page text!

            //System.out.println(textStrings.toString().indexOf(entry.getKey()));

                // 2.2. Find the text pattern matches!
                final Matcher matcher = pattern.matcher(TextExtractor.toString(textStrings));
                // 2.3. Highlight the text pattern matches!
                textExtractor.filter(textStrings, new TextExtractor.IIntervalFilter() {
                    public boolean hasNext() {
                        // System.out.println(matcher.find());
                        // if(key.getMatchCriteria() == 1){
                        if (matcher.find()) {
                            return true;
                        }
                        /*
                         * } else if(key.getMatchCriteria() == 2) { if
                         * (matcher.hitEnd()) { count++; return true; } }
                         */
                        return false;

                    }

                    public Interval<Integer> next() {
                        return new Interval<Integer>(matcher.start(), matcher.end());
                    }

                    public void process(Interval<Integer> interval, ITextString match) {
                        // Defining the highlight box of the text pattern
                        // match...
                        System.out.println(match);
                    /*  List<Quad> highlightQuads = new ArrayList<Quad>();
                        {
                            Rectangle2D textBox = null;
                            for (TextChar textChar : match.getTextChars()) {
                                Rectangle2D textCharBox = textChar.getBox();
                                if (textBox == null) {
                                    textBox = (Rectangle2D) textCharBox.clone();
                                } else {
                                    if (textCharBox.getY() > textBox.getMaxY()) {
                                        highlightQuads.add(Quad.get(textBox));
                                        textBox = (Rectangle2D) textCharBox.clone();
                                    } else {
                                        textBox.add(textCharBox);
                                    }
                                }
                            }
                            textBox.setRect(textBox.getX(), textBox.getY(), textBox.getWidth(), textBox.getHeight());
                            highlightQuads.add(Quad.get(textBox));
                        }*/
                        List<Quad> highlightQuads = new ArrayList<Quad>();
                        List<TextChar> textChars = match.getTextChars();
                        Rectangle2D firstRect = textChars.get(0).getBox();
                        Rectangle2D lastRect = textChars.get(textChars.size()-1).getBox();
                        Rectangle2D rect = firstRect.createUnion(lastRect);
                        highlightQuads.add(Quad.get(rect).get(rect));
                        // subtype can be Highlight, Underline, StrikeOut, Squiggly


                        new TextMarkup(page, highlightQuads, translationKeyword, MarkupTypeEnum.Highlight);

                    }

                    public void remove() {
                        throw new UnsupportedOperationException();
                    }

                });
            }

        }

        SerializationModeEnum serializationMode = SerializationModeEnum.Standard;

            file.save(new java.io.File(outputPath), serializationMode);

            System.out.println("file created");
            long endTime = System.currentTimeMillis();

             System.out.println("seconds take for execution is:"+(endTime-startTime)/1000);

        } catch (Exception e) {
               e.printStackTrace();
        }
        finally{
            in.close();
        }


    }
}

Пожалуйста, найдите вложение выходного изображения

Просьба предоставить свои данные, чтобы выделить конкретное ключевое слово для поиска не английских PDF-файлов.

Я использую ключевое слово в тексте ниже, который находится на китайском языке.

普 双 套 习近平 修宪 普京 利用 双 套 车 绕开 宪法 装 班 要走 普京

введите описание изображения здесь

1 ответ

Решение

Ваша версия PDF клоуна

Версия PDF Clown, которую вы получили здесь из репозитория Tymate Maven на github, была перенесена туда 23 апреля 2015 года. С другой стороны, последняя (на данный момент) регистрация в хранилище исходного кода PDF-файла клоуна TROWK на sourceforge - это с 27 мая 2015 года. На самом деле после 23 апреля 2015 года происходит около 30 проверок. Таким образом, вы определенно не используете самую последнюю версию этого явно мертвого проекта библиотеки PDF.

Использование текущего снимка 0.2.0

Я протестировал ваш код с версией разработки 0.2.0, скомпилированной из этого транка, и результат действительно отличается:

скриншот все еще глючит

Это лучше, поскольку блики имеют ширину искомого символа и расположены ближе к фактической позиции символа. Тем не менее, здесь все еще есть ошибка, поскольку основные моменты второго и третьего матчей несколько не совпадают.

Исправление ошибки

Оставшаяся проблема на самом деле не связана с языком текста. Это просто ошибка в обработке одного типа команд рисования текста в PDF, так что это можно наблюдать в документах с текстом на произвольных языках. Из-за того, что эти команды в настоящее время используются очень редко, однако, ошибка почти никогда не наблюдается, не говоря уже о сообщении. Ваш PDF, с другой стороны, использует такие команды рисования текста.

Ошибка в ShowText класс (пакет org.pdfclown.documents.contents.objects). В конце scan Метод текстовой строки матрицы в графическом состоянии обновляется следующим образом, если ShowText Экземпляр на самом деле является ShowTextToNextLine Экземпляр, полученный из него:

if(textScanner == null)
{
  state.setTm(tm);

  if(this instanceof ShowTextToNextLine)
  {state.setTlm((AffineTransform)tm.clone());}
}

Матрица текстовой строки здесь устанавливается на текстовую матрицу после перехода к следующей строке и рисования текста. Это неправильно, вместо этого необходимо установить текстовую матрицу сразу после перехода к следующей строке перед рисованием текста.

Это можно исправить, например, так:

if(textScanner == null)
{
  state.setTm(tm);

  if(this instanceof ShowTextToNextLine)
    state.getTlm().concatenate(new AffineTransform(1, 0, 0, 1, 0, -state.getLead()));
}

С этим изменением на месте результат выглядит так:

скриншот исправлен

Другие вопросы по тегам