使用 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 所做的。我会更新我的答案。 @Vladooutput
是文件的路径。以上是关于使用 iTextSharp 将图像转换为 PDF 保留剪切路径的主要内容,如果未能解决你的问题,请参考以下文章
使用 ITextSharp 将 HTML 文件转换为 PDF 文件
使用 iTextSharp 将 HTML 样式(点下划线)转换为 PDF
使用itextsharp xmlworker 将html转换为pdf并垂直写入文本