pdf小丑 - 不突出显示特定的搜索关键字

时间:2018-01-23 06:52:08

标签: java pdfclown

我正在使用带pdfclown-0.2.0-HEAD.jar的pdf-clown。我编写了以下代码,用于突出显示搜索中文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();
        }


    }
}

Please find the attachment of output image

请提供您的输入,以突出显示非英语pdf文件的特定搜索关键字。

我在下面的文字中搜索关键字,这是中文语言。

  

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

enter image description here

1 个答案:

答案 0 :(得分:0)

您的PDF小丑版

您从github上的here maven存储库中检索到的Tymate's的PDF Clown版本已于2015年4月23日推送到那里。最终(截至目前)签到PDF Clown subversion另一方面,Sourceforge上的源代码库TRUNK是从2015年5月27日开始的。2015年4月23日之后实际上有大约30个签到。因此,你绝对不会使用这个显然死的PDF库项目的最新版本。

使用当前的0.2.0快照

我使用从该主干编译的0.2.0开发版测试了您的代码,结果确实不同:

screenshot still somewhat buggy

更好的是,高光部分具有所寻找角色的宽度并且更靠近实际角色位置。但是仍然存在一个错误,因为第二和第三场比赛的亮点有点偏离。

修复错误

其余问题实际上与文本语言无关。它只是处理一种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()));
}

如果发生这种变化,结果将如下所示:

screenshot fixed