微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

iTextSharp 用另一个 PDF 替换图像 更新

如何解决iTextSharp 用另一个 PDF 替换图像 更新

我有一个包含一些图像的 PDF 文件,我想用其他一些 PDF 替换它。代码通过pdf并获取图像引用:

PdfDocument pdf = new PdfDocument(new PdfReader(args[0]),new PdfWriter(args[1]));
for(int i=1; i<=pdf.GetNumberOfPages(); ++i)
{
    PdfDictionary pageDict  = pdf.GetPage(i).GetPdfObject();
    PdfDictionary resources = pageDict.GetAsDictionary(PdfName.Resources);
    PdfDictionary xObjects  = resources.GetAsDictionary(PdfName.XObject);

    foreach (PdfName imgRef in xObjects.KeySet())
    {
        // image reference
    }
}

对于我的所有图像,我都有一个相应的 PDF,我想用它来替换图像。我尝试的是将 Put一个 PDF(始终是单页)作为对象:

PdfDocument other = new PdfDocument(new PdfReader("replacement.pdf"));
xObjects.Put(imgRef,other.GetFirstPage().GetPdfObject().Clone());

但是在关闭 PdfDocument 时抛出异常:

iText.Kernel.PdfException: 'Pdf indirect object belongs to other PDF document. copy object to current pdf document.'

如何实现用另一个PDF(的内容)替换图像?


更新

我还尝试了其他一些方法,可能会改善结果。为了克服之前的错误消息,我通过以下方式将该页面复制到原始 pdf:

var page = other.GetFirstPage().copyTo(pdf);

但是,替换 xObject 不起作用:

xObjects.Put(imgRef,page.GetPdfObject());

导致 PDF 损坏。

解决方法

要将原始页面复制到另一个文档中用作图像替换,您可以使用 PdfPage#CopyAsFormXObject

让我们假设我们有这个 PDF 作为模板,我们想用另一个 PDF 的内容替换沙漠的图像:

template

我们还假设要用作替换的 PDF 如下所示:

insertion

问题是,如果我们盲目地用 PDF 的内容替换原始图像,很可能会得到这样的结果:

potential result

因此,我们会感觉一切都运行良好,但视觉效果仍然很差。问题是坐标对于普通光栅图像和矢量 XObject(PDF 替换)的工作方式略有不同。所以我们还需要调整我们新创建的 XObject 的变换矩阵(/Matrix 键)。

所以代码看起来像这样:

PdfDocument pdf = new PdfDocument(new PdfReader(@"template.pdf"),new PdfWriter(@"out.pdf"));
for(int i=1; i<=pdf.GetNumberOfPages(); ++i) {
    PdfDictionary pageDict  = pdf.GetPage(i).GetPdfObject();
    PdfDictionary resources = pageDict.GetAsDictionary(PdfName.Resources);
    PdfDictionary xObjects  = resources.GetAsDictionary(PdfName.XObject);

    IDictionary<PdfName,PdfStream> toReplace = new Dictionary<PdfName,PdfStream>();
    
    foreach (PdfName imgRef in xObjects.KeySet()) {
        PdfStream previousXobject = xObjects.GetAsStream(imgRef);
        PdfDocument imageReplacementDoc =
            new PdfDocument(new PdfReader(@"insert.pdf"));
        PdfXObject imageReplacement = imageReplacementDoc.GetPage(1).CopyAsFormXObject(pdf);
        toReplace[imgRef] = imageReplacement.GetPdfObject();
        adjustXObjectSize(imageReplacement);
        imageReplacementDoc.Close();
    }

    foreach (var x in toReplace) {
        xObjects.Put(x.Key,x.Value);
    }
}
pdf.Close();

在我描述的示例上运行上述代码后的视觉结果如下:

result

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。