我正在使用PDFClown分析和使用PDFDocuments。我的目的是突出显示表格中的所有数字。对于所有属于在一起的数字(例如:表的一列中的所有数字),我将创建一个带有四边形列表的TextMarkup。首先,看起来一切都可以正常工作:左侧的所有突出显示都属于一个TextMarkup,而右侧的所有突出显示都属于另一个TextMarkup。

java - PDFClown:创建TextMarkup会导致TextMarkup的框不正确-LMLPHP

但是,当分析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);
}


这是一个示例文件Example

谢谢 !!

最佳答案

您的代码并不是真正的独立代码(我无法运行它,因为它特别会丢失输入数据),因此我只能做一些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小丑错误?

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

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

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

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

10-08 08:40