如何从 pdf 中提取视口并根据视口修改注释的边界矩形?

问题描述 投票:0回答:1

我已经实现了使用 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 的 link ,其中使用上述代码修改其坐标后放置标记。标记根本不会出现。

java pdf pdfbox viewport
1个回答
1
投票

此代码(不会避免 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 内。您所需要做的就是调整注释的矩形。

© www.soinside.com 2019 - 2024. All rights reserved.