0

我正在使用 PDFClown 来分析和使用 PDFDocuments。我的目标是突出显示表格中的所有数字。对于属于一起的所有数字(例如:表格一列中的所有数字),我将创建一个带有四边形列表的 TextMarkup。首先,看起来everythink 运行良好:左侧的所有高亮属于一个TextMarkup,右侧的所有高亮属于另一个TextMarkup。

高亮文本

但是在分析 TextMarkup 的大小时,大小比它看到的图片要大。因此,当在左侧 TextMarkup 框周围绘制一个矩形时,尽管左侧 TextMarkup 没有突出显示与另一列相交,但该矩形与另一列相交。有没有办法优化 TextMarkup 的 Box?我认为盒子有一个球根状的结尾,所以盒子与另一个 TextMarkup 相交

这是创建 TextMarkup 的代码:

List<Quad> highlightQuads = new ArrayList<Quad>();
for (TextMarkup textMarkup : textMarkupsForOneAnnotation) {
    Rectangle2D textBox = textMarkup.getBox();
    Rectangle2D.Double rectangle = new Rectangle2D.Double(textBox.getX(), textBox.getY(), textBox.getWidth(), textBox.getHeight());
    highlightQuads.add(Quad.get(rectangle));
}

if (highlightQuads.size() > 0) {

    TextMarkup _textMarkup = new TextMarkup(pagesOfNewFile.get(lastFoundNewFilePage).getPage(), highlightQuads,"", MarkupTypeEnum.Highlight);       
    _textMarkup.setColor(DeviceRGBColor.get(Color.GREEN));
    _textMarkup.setVisible(true);
    allTextMarkUps.add(_textMarkup);
}

这是一个示例文件示例

谢谢你 !!

4

1 回答 1

1

您的代码并不是真正独立的(我无法运行它,因为它特别错过了输入数据),所以我只能做一些 PDF Clown 代码分析。但是,该代码分析确实出现了一个 PDF Clown 实现细节,可以解释您的观察。

PDF Clown 如何计算标注标注的尺寸?

标记注释矩形必须足够大,以包含所有四边形以及开始和结束装饰(标记矩形上的圆形左右大写字母)。

PDF Clown 计算这个矩形如下TextMarkup

  public void setMarkupBoxes(
    List<Quad> value
    )
  {
    PdfArray quadPointsObject = new PdfArray();
    double pageHeight = getPage().getBox().getHeight();
    Rectangle2D box = null;
    for(Quad markupBox : value)
    {
      /*
        NOTE: Despite the spec prescription, Point 3 and Point 4 MUST be inverted.
      */
      Point2D[] markupBoxPoints = markupBox.getPoints();
      quadPointsObject.add(PdfReal.get(markupBoxPoints[0].getX())); // x1.
      quadPointsObject.add(PdfReal.get(pageHeight - markupBoxPoints[0].getY())); // y1.
      quadPointsObject.add(PdfReal.get(markupBoxPoints[1].getX())); // x2.
      quadPointsObject.add(PdfReal.get(pageHeight - markupBoxPoints[1].getY())); // y2.
      quadPointsObject.add(PdfReal.get(markupBoxPoints[3].getX())); // x4.
      quadPointsObject.add(PdfReal.get(pageHeight - markupBoxPoints[3].getY())); // y4.
      quadPointsObject.add(PdfReal.get(markupBoxPoints[2].getX())); // x3.
      quadPointsObject.add(PdfReal.get(pageHeight - markupBoxPoints[2].getY())); // y3.
      if(box == null)
      {box = markupBox.getBounds2D();}
      else
      {box.add(markupBox.getBounds2D());}
    }
    getBaseDataObject().put(PdfName.QuadPoints, quadPointsObject);

    /*
      NOTE: Box width is expanded to make room for end decorations (e.g. rounded highlight caps).
    */
    double markupBoxMargin = getMarkupBoxMargin(box.getHeight());
    box.setRect(box.getX() - markupBoxMargin, box.getY(), box.getWidth() + markupBoxMargin * 2, box.getHeight());
    setBox(box);

    refreshAppearance();
  }

  private static double getMarkupBoxMargin(
    double boxHeight
    )
  {return boxHeight * .25;}

因此,它采用所有四边形的边界框并添加左右边距,每个边距宽度为整个边界框高度的四分之一

你的情况是什么结果?

虽然如果只有一个四边形,这种添加的边距宽度是明智的,但如果您的标记注释包含许多相互重叠的四边形,这会导致巨大的、不必要的边距。

如何改进代码?

由于添加的大写取决于单个大写而不是它们的组合边界框,因此可以通过使用单个四边形的最大高度而不是所有四边形的边界框的高度来改进代码,例如:

Rectangle2D box = null;
double maxQuadHeight = 0;
for(Quad markupBox : value)
{
  double quadHeight = markupBox.getBounds2D().getHeight();
  if (quadHeight > maxQuadHeight)
    maxQuadHeight = quadHeight;
  ...
}
...
double markupBoxMargin = getMarkupBoxMargin(maxQuadHeight);
box.setRect(box.getX() - markupBoxMargin, box.getY(), box.getWidth() + markupBoxMargin * 2, box.getHeight());
setBox(box);

如果您不想为此修补 PDF Clown,您也可以在构造TextMarkup _textMarkup纠正预先计算的注释矩形后执行此代码(稍作修改)。

这是在修复 PDF Clown 错误吗?

这不是错误,因为文本标记注释矩形不需要最小;PDF Clown 还可以始终为每个此类注释使用整个裁剪框。

不过,我会假设代码的作者想要计算一个最小的矩形,但只针对单行进行了优化,因此在某种程度上没有达到他自己的期望......

这段代码还有其他问题吗?

是的。标记注释标记的文本不必是水平的,它可能有一个角度,甚至可以是垂直的。在这种情况下,注释矩形的顶部和底部也需要一些边距,而不是(仅)在左侧和右侧。

于 2017-09-04T11:14:04.893 回答