繁体   English   中英

更改PDF中所有链接目标的缩放级别

[英]Changing the zoom level in all link destinations in PDFs

改变使用缩放级别的代码iTextJava在被赋予在iText的主页 我想将其转换为C# 经过无数小时后,我终于重写了代码,只是发现它没有更改任何链接。 这意味着我一定犯了错误。

编辑:

根据要求,请看一个简单的PDF示例

我的代码如下:

using (var reader = new PdfReader(input))
{
    using (var stamper = new PdfStamper(reader, ms))
    {
        for (int i = 1; i <= reader.NumberOfPages; i++)
        {
            // Get a page of a PDF page
            PdfDictionary page = reader.GetPageN(i);

            // Get all the annotations of page i
            PdfArray annotsArray = page.GetAsArray(PdfName.ANNOTS);

            // If page does not have annotations
            if (annotsArray == null)
            {
                continue;
            }

            // For each annotation
            for (int j = 0; j < annotsArray.Size; j++)
            {
                // for current annotation
                PdfDictionary annotation = annotsArray.GetAsDict(j);

                // test if it is LINK
                PdfDictionary annotationAction = annotation.GetAsDict(PdfName.A);
                if ( annotationAction == null || PdfName.LINK.Equals(annotationAction.Get(PdfName.S)) )
                {
                    PdfArray d = annotation.GetAsArray(PdfName.DEST);
                    if (d != null && d.Length == 5 && PdfName.XYZ.Equals(d.GetAsName(1)))
                    {
                        d[4] = new PdfNumber(150);
                    }
                }

            }
        }
    }
}

Java中的原始代码要短得多:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfDictionary page = reader.getPageN(11);
        PdfArray annots = page.getAsArray(PdfName.ANNOTS); 
        for (int i = 0; i < annots.size(); i++) {
            PdfDictionary annotation = annots.getAsDict(i);
            if (PdfName.LINK.equals(annotation.getAsName(PdfName.SUBTYPE))) {
                PdfArray d = annotation.getAsArray(PdfName.DEST);
                if (d != null && d.size() == 5 && PdfName.XYZ.equals(d.getAsName(1)))
                    d.set(4, new PdfNumber(0));
            }
        }
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        stamper.close();
    }

更新的编辑2

感谢@mkl,我提出了解决方案。

for (int i = 1; i <= reader.NumberOfPages; i++)
{
    PdfDictionary page = reader.GetPageN(i);

    PdfArray annotsArray = page.GetAsArray(PdfName.ANNOTS);

    if (annotsArray == null)
    {
        continue;
    }

    for (int j = 0; j < annotsArray.Size; j++)
    {
        PdfDictionary annotation = annotsArray.GetAsDict(j);

        PdfDictionary annotationAction = annotation.GetAsDict(PdfName.A);
        if (PdfName.GOTO.Equals(annotationAction.Get(PdfName.S)))
        {
            PdfArray d = annotationAction.GetAsArray(PdfName.D);
            if (d != null)
            {
                Console.WriteLine(d[4]);
                d[4] = new PdfNumber(1.20);
            }

        }

    }
}    

不确定您是否使用其他PDF作为输入,但是使用iText网站上的源PDF作为问题中链接到的示例,这对我有用,并将所有链接的缩放级别更改为文档缩放级别:

using (reader)
{
    PdfDictionary page = reader.GetPageN(11);
    PdfArray annots = page.GetAsArray(PdfName.ANNOTS);
    for (int i = 0; i < annots.Size; i++)
    {
        PdfDictionary annotation = annots.GetAsDict(i);
        if (PdfName.LINK.Equals(annotation.GetAsName(PdfName.SUBTYPE)))
        {
            PdfArray d = annotation.GetAsArray(PdfName.DEST);
            if (d != null && d.Size == 5 && PdfName.XYZ.Equals(d.GetAsName(1)))
                d.Set(4, new PdfNumber(0));
        }
    }
    using (var stream = new MemoryStream())
    {
        using (var stamper = new PdfStamper(reader, stream)) { }
        File.WriteAllBytes(outputFile, stream.ToArray());
    }
}

如果您查看链接注释的规范,您将看到

字典 (可选; PDF 1.1)时,链接注释被激活时,应执行的操作(见12.6,“操作”)。

目的地数组,名称或字节字符串(可选;如果存在A条目,则不允许)激活注释时应显示的目的地(请参见12.3.2,“目的地”)。

(表173 –特定于链接注释的其他条目-ISO 32000-1)

也就是说,原始Java代码和您的端口都仅处理一种Link注释,即一种使用Dest条目的注释。

但是,在检查示例PDF时,可以找到带有A条目的链接注释,例如

/A <<
    /D  [ 1 /XYZ 0.000001 842 0.724 ]   
    /S  /GoTo   
>>

因此,您的代码必须考虑所有可能的选项。 特别是如果你操作PDF有定义的,而不是一个目的地萌发的一个A ction,就必须正确处理在A ction而不是仅仅不存在链接 目的地萌发的的d estination。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM