我已经实现了使用PDFBox将链接注释添加到任何PDF的功能。它适用于大多数PDF,但对于某些PDF,它不将标记放置在正确的坐标处。当我在某些PDF编辑器中打开PDF时,它给了我警告,PDF包含一个无标题的视口,可能会影响该PDF的测量值。因此,我觉得视口很可能导致了问题。是否有一种方法可以根据视口修改标记的坐标,以便将其放置在PDF中正确的位置。这是一个包含视口的PDF的链接。
根据蒂尔曼(Tilman)的建议,我从视口措施词典中提取了C条目。并试图修改矩形的坐标,但没有在正确的位置添加它们。我尝试过的代码。另外,视口对注释没有影响,但是当我尝试将某些东西吸入PDF时,这会引起问题。
COSArray vps = (COSArray)page.getCOSObject().getDictionaryObject(COSName.getPDFName("VP"));
if (vps != null)
{
for (int v = 0; v < vps.size(); ++v)
{
COSDictionary vp = (COSDictionary)vps.getObject(v);
PDViewportDictionary viewportDict = new PDViewportDictionary(vp);
PDRectangle vpRect = viewportDict.getBBox();
PDMeasureDictionary measureDict = viewportDict.getMeasure();
PDRectlinearMeasureDictionary rectilinearDict = new PDRectlinearMeasureDictionary(measureDict.getCOSObject());
bool pointLieInVP = UtilityClass.RectangleContainsPoint(new PointF(leftX, bottomY), vpRect);
if (pointLieInVP)
{
COSArray xArray = (COSArray)measureDict.getCOSObject().getDictionaryObject(COSName.getPDFName("X"));
float xScale = 1;
if (xArray!=null)
{
xScale = ((COSFloat)(((COSDictionary)xArray.getObject(0)).getDictionaryObject(COSName.getPDFName("C")))).floatValue();
}
leftX /= xScale;
rightX /= xScale;
COSBase yObj = measureDict.getCOSObject().getDictionaryObject(COSName.getPDFName("Y"));
if (yObj != null)
{
COSArray yArray = (COSArray)yObj;
float yScale = ((COSFloat)(((COSDictionary)yArray.getObject(0)).getDictionaryObject(COSName.getPDFName("C")))).floatValue();
bottomY /= yScale;
topY /= yScale;
}
else
{
bottomY /= xScale;
topY /= xScale;
}
}
}
}
这是添加PDF标记的链接,而无需调整视口。5个红色标记在页面的右下角添加。但是它们应该放在PDF中的链接注释上,该注释位于正确位置。这是PDF的链接,其中在使用上述代码修改其坐标后放置标记。标记根本没有出现。
此代码(不避免ClassCastExceptions)将向您显示每个页面中的视口:
try (PDDocument doc = PDDocument.load(new File("S115-STRUCTURALHIGH ROOF FRAMING(WEST)ENLARGED PLANS.pdf")))
{
for (int p = 0; p < doc.getNumberOfPages(); ++p)
{
PDPage page = doc.getPage(p);
COSArray vps = (COSArray) page.getCOSObject().getDictionaryObject(COSName.getPDFName("VP"));
if (vps != null)
{
for (int v = 0; v < vps.size(); ++v)
{
COSDictionary vp = (COSDictionary) vps.getObject(v);
PDRectangle rect = new PDRectangle((COSArray) vp.getDictionaryObject(COSName.BBOX));
System.out.println("Viewport " + vp.getString(COSName.NAME) + ": " + rect);
}
}
}
}
如何调整注释取决于您...很可能,这些应该在Bbox内部。您需要做的就是调整注释的矩形。