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

3
我们希望以程序化的方式将大量图像转换为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)。 - Bruno Lowagie
我在你的代码中发现了一个错误:第一张图片的页面大小总是会出错。它将是A4而不是图像的大小。您需要使用遇到的第一张图像的大小创建“文档”对象。 - Bruno Lowagie
我已经编辑了你的标题。请参考“问题的标题应该包含“标签”吗?”,在那里达成共识是“不应该”。 - John Saunders
@BrunoLowagie 关于您指出的错误,我们并没有注意到它,并且我们已经对数百张图像进行了测试,每个图像的大小都是正确的。 - Lars Thorén
@LarsThorén 好的,我已经发布了一个带有更多澄清的答案。也许那会有所帮助。(正如您可能已经注意到的那样,我是iText的原始作者。) - Bruno Lowagie
1个回答

5
iText将JPG的字节直接复制到PDF中,没有任何一个字节被更改。如果你说你的JPG有剪辑路径(我从未听说过这种东西),并且在PDF中没有看到该特性,则面临的是PDF固有的限制,而不是iText的限制。iText甚至不查看JPG字节:它只创建带有DCTDecode过滤器的PDF流对象。
您必须在将图像添加到PDF之前应用剪辑路径。正如您可能知道的那样,PDF不支持PNG,而PNG支持透明度。当iText遇到透明PNG时,它会处理PNG。它会创建两个图像:一个使用/FlateDecode的不透明图像和一个使用/FlateDecode的单色图像。将单色图像作为遮罩添加到不透明图像中以获得透明度。我想您需要以类似的方式预处理JPG。
关于内联图像:
不要使用内联图像:使用内联图像意味着图像存储在PDF的内容流中,而不是存储为图像XObject(这是存储图像的最佳方式)。内联图像仅适用于大小为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() 方法将被忽略,页面大小也不会更改。您仍将停留在页面1并保持A4大小。

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),它在转换之前内部处理此问题,应用剪辑路径。 - Lars Thorén
是的,iText可以处理透明PNG图片。我会更新我的回答。 - Bruno Lowagie
1
@Vlado output 是一个文件路径。 - Bruno Lowagie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接