使用 iTextSharp 将图像转换为 PDF 保留剪切路径

Posted

技术标签:

【中文标题】使用 iTextSharp 将图像转换为 PDF 保留剪切路径【英文标题】:Converting images to PDF with iTextSharp preserve clipping path 【发布时间】:2015-08-11 23:16:37 【问题描述】:

我们希望以编程方式将批量图像转换为 PDF。到目前为止,看起来我们将使用 iTextSharp,但我们遇到了带有剪切路径的 JPG 图像的问题。我们在测试中使用以下代码:

using (FileStream fs = new FileStream(output, FileMode.Create, FileAccess.Write, FileShare.None))

    using (Document doc = new Document())
    
        using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
        
            doc.Open();
            iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(source);

            image.SetAbsolutePosition(0, 0);
            doc.SetPageSize(new iTextSharp.text.Rectangle(0, 0, image.Width, image.Height, 0));
            doc.NewPage();

            writer.DirectContent.AddImage(image,false); 

            doc.Close();
        
    

JPG 图像中的剪切路径似乎被丢弃了。有没有办法保留剪切路径?另外,在调用 AddImage 时,还有一个 InlineImage 选项,有人知道这是做什么的吗?

【问题讨论】:

不要使用内嵌图像:使用内嵌图像意味着图像存储在PDF的内容流中。这只能用于大小为 4 KB 或更小的图像。 PDF 2.0 将禁止使用较大的内嵌图像。此外:iText 将 JPG 的字节直接复制到 PDF 中。没有一个字节被改变。如果您说您的 JPG 具有剪切路径(我从未听说过这样的事情)并且您在 PDF 中看不到该功能,那么您将面临 PDF 固有的限制,而不是 iText(iText 没有连看 JPG 都不看)。 我确实在您的代码中看到了一个错误:第一个图像的页面大小总是错误的。它将是 A4 而不是图像的大小。您需要使用遇到的第一张图片的大小创建Document 对象。 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。 @BrunoLowagie 关于你指出的错误,我们没有注意到它,我们已经对数百张图片进行了测试,每张图片的尺寸都是正确的。 @LarsThorén 好的,我已经发布了一个包含更多说明的答案。也许这有帮助。 (您可能已经注意到,我是 iText 的原作者。) 【参考方案1】:

iText 将 JPG 的字节直接复制到 PDF 中。没有一个字节被改变。如果您说您的 JPG 具有剪切路径(我从未听说过这样的事情)并且您在 PDF 中看不到该功能,那么您将面临 PDF 固有的限制,而不是 iText。 iText 甚至不查看 JPG 字节:它只是使用过滤器 DCTDecode 创建一个 PDF 流对象。

您必须在将图像添加到 PDF 之前应用剪切路径。您可能知道,PDF 不支持 PNG,而 PNG 支持透明度。当 iText 遇到透明 PNG 时,它会处理该 PNG。它创建了两张图像:一张使用/FlateDecode 的不透明图像和一张使用/FlateDecode 的单色图像。不透明图像与单色图像一起添加作为其蒙版以获得透明度。我想你必须以类似的方式预处理你的 JPG。

关于内嵌图片:

不要使用内嵌图像:使用内嵌图像意味着图像存储在 PDF 的内容流中,而不是存储为 Image XObject(这是在 PDF 中存储图像的最佳方式)。内联图像只能用于大小为 4 KB 或更小的图像。 PDF 2.0 将禁止使用较大的内嵌图像。

补充说明:

我认为我在您的代码中发现了问题。您正在创建页面大小为 A4 的文档:

Document doc = new Document()

当您不将参数传递给Document 构造函数时,A4 是默认大小。之后,您尝试像这样更改页面大小:

doc.SetPageSize(new iTextSharp.text.Rectangle(0, 0, image.Width, image.Height, 0));
doc.NewPage();

但是:由于您还没有在第一页添加任何内容,NewPage() 方法将被忽略并且页面大小不会改变。您仍会在 A4 尺寸的第 1 页上。

iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(source);
using (FileStream fs = new FileStream(output, FileMode.Create, FileAccess.Write, FileShare.None))

    using (Document doc = new Document(image))
    
        using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
        
            doc.Open();
            image.SetAbsolutePosition(0, 0);
            writer.DirectContent.AddImage(image); 
            doc.Close();
         
     

【讨论】:

好的,iText 只是复制图像是有道理的,然后我明白剪切路径将被丢弃,因为 PDF 不支持剪切路径。还有其他软件替代品,例如 ImageMagick (+GhostScript),它在内部处理此问题,在转换之前应用剪切路径。 是的,这就是 iText 对透明 PNG 所做的。我会更新我的答案。 @Vlado output 是文件的路径。

以上是关于使用 iTextSharp 将图像转换为 PDF 保留剪切路径的主要内容,如果未能解决你的问题,请参考以下文章

使用 itextsharp 将 HTML 转换为 PDF

使用 ITextSharp 将 HTML 文件转换为 PDF 文件

使用 iTextSharp 将 HTML 样式(点下划线)转换为 PDF

使用itextsharp xmlworker 将html转换为pdf并垂直写入文本

如何使用 iText 将带有图像和超链接的 HTML 转换为 PDF?

使用 PDF itextSharp 可以在创建 pdf 文档时将图像放在文本之上