[英]Text Highlighting with PDFClown without using PDF Annotations
我幾周前開始使用PDFClown。 我的目的是多單詞突出顯示,主要是在報紙上。 從org.pdfclown.samples.cli.TextHighlightSample
示例開始,我成功提取了多個單詞的位置並突出顯示了它們。 在大多數情況下,我什至解決了一些由於文本排序和匹配導致的問題。
不幸的是,我的框架包括FPDI ,並且沒有考慮PDFAnnotations
。 因此,頁面內容流之外的所有內容(例如文本注釋和其他所謂的標記注釋)都會丟失。
那么關於在不使用PDF注釋的情況下使用PdfClown創建“文本突出顯示”的任何建議嗎?
為了在注釋中沒有高亮顯示,而是在實際的頁面內容流中顯示突出顯示,必須將圖形突擊隊員放入頁面內容流中,在org.pdfclown.samples.cli.TextHighlightSample
示例的情況下,將其隱式地放入普通內容中。注釋外觀流。
可以這樣實現:
org.pdfclown.files.File file = new org.pdfclown.files.File(resource);
Pattern pattern = Pattern.compile("S", Pattern.CASE_INSENSITIVE);
TextExtractor textExtractor = new TextExtractor(true, true);
for (final Page page : file.getDocument().getPages())
{
final List<Quad> highlightQuads = new ArrayList<Quad>();
Map<Rectangle2D, List<ITextString>> textStrings = textExtractor.extract(page);
final Matcher matcher = pattern.matcher(TextExtractor.toString(textStrings));
textExtractor.filter(textStrings, new TextExtractor.IIntervalFilter()
{
@Override
public boolean hasNext()
{
return matcher.find();
}
@Override
public Interval<Integer> next()
{
return new Interval<Integer>(matcher.start(), matcher.end());
}
@Override
public void process(Interval<Integer> interval, ITextString match)
{
{
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);
}
}
}
highlightQuads.add(Quad.get(textBox));
}
}
@Override
public void remove()
{
throw new UnsupportedOperationException();
}
});
// Highlight the text pattern match!
ExtGState defaultExtGState = new ExtGState(file.getDocument());
defaultExtGState.setAlphaShape(false);
defaultExtGState.setBlendMode(Arrays.asList(BlendModeEnum.Multiply));
PrimitiveComposer composer = new PrimitiveComposer(page);
composer.getScanner().moveEnd();
// TODO: reset graphics state here.
composer.applyState(defaultExtGState);
composer.setFillColor(new DeviceRGBColor(1, 1, 0));
{
for (Quad markupBox : highlightQuads)
{
Point2D[] points = markupBox.getPoints();
double markupBoxHeight = points[3].getY() - points[0].getY();
double markupBoxMargin = markupBoxHeight * .25;
composer.drawCurve(new Point2D.Double(points[3].getX(), points[3].getY()),
new Point2D.Double(points[0].getX(), points[0].getY()),
new Point2D.Double(points[3].getX() - markupBoxMargin, points[3].getY() - markupBoxMargin),
new Point2D.Double(points[0].getX() - markupBoxMargin, points[0].getY() + markupBoxMargin));
composer.drawLine(new Point2D.Double(points[1].getX(), points[1].getY()));
composer.drawCurve(new Point2D.Double(points[2].getX(), points[2].getY()),
new Point2D.Double(points[1].getX() + markupBoxMargin, points[1].getY() + markupBoxMargin),
new Point2D.Double(points[2].getX() + markupBoxMargin, points[2].getY() - markupBoxMargin));
composer.fill();
}
}
composer.flush();
}
file.save(new File(RESULT_FOLDER, "multiPage-highlight-content.pdf"), SerializationModeEnum.Incremental);
( HighlightInContent.java方法testHighlightInContent)
您將從原始示例中識別出文本提取框架。 現在僅需要處理整個頁面中的四邊形,然后再對其進行處理,並且處理代碼(大部分代碼是從TextMarkup.refreshAppearance()
借用的)將代表四邊形的表單繪制到頁面內容中。
請注意,要使該功能正常工作,必須在插入新指令之前重置圖形狀態(該位置標記有TODO
注釋)。 這可以通過應用保存/恢復狀態或通過實際抵消不需要的已更改狀態條目來完成。 不幸的是,我沒有在PDF Clown中看到如何做前者,並且還沒有時間去做后者。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.