我从包含.png的电子邮件中生成了第1000个PDF(我不是生成器的所有者)。由于某些原因,使用我正在使用的成像系统渲染这些PDF非常慢(我不是该系统的开发者,可能不会更改它)。
如果我使用iTextSharp并实现IRenderListener来计算要渲染的图像,则每页有数千个(99%仅为1或2个像素)。但是,如果我计算PDF资源中的图像,只有少数(〜几十)。
我在每页的资源中计算图像,并在
之后使用此处的代码var dict = pdfReader.GetPageN(currentPage)
PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(dict.Get(PdfName.RESOURCES));
PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT));
if (xobj != null)
{
foreach (PdfName name in xobj.Keys)
{
PdfObject obj = xobj.Get(name);
if ((obj.IsIndirect()))
{
PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);
PdfName subtype = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));
if (PdfName.IMAGE.Equals(subtype))
{
Count++
我的IRenderListener看起来像这样:
class ImageRenderListener : IRenderListener
{
public void RenderImage(iTextSharp.text.pdf.parser.ImageRenderInfo renderInfo)
{
PdfImageObject image = renderInfo.GetImage();
if (image == null) return;
var refObj = renderInfo.GetRef();
if (refObj == null)
Count++; // but why no ref ??
else
Count++;
}
我刚刚开始学习PDF规范和今晚的iTextSharp,分析我的PDF并了解可能出现的问题......如果我是正确的,我会看到许多要呈现的图像没有引用资源(refObj) == null)并且它们是.png(image.streamContentType.FileExtension =" png")。所以,我认为这些图像使渲染变得如此缓慢......
出于测试目的,我想从PDF中删除这些图像,但不知道如何继续。
我只找到代码示例来删除资源中的图片...但我要删除的图片不是:/
是否有任何代码示例可以帮助我?我确实在google" iTextSharp删除了对象"等...但是没有类似于我的情况:(
答案 0 :(得分:2)
让我首先直截了当地观察到你有一个糟糕的PDF。
在PDF查看器中打开PDF时看到的图像似乎由几个小的1或2像素图像组成。无论您使用哪种成像系统,逐个显示这些像素的绘图操作都不是最理想的:您将遇到错误的PDF。
在您的第一个片段中,我看到您遍历存储在每个页面的XObject资源中的所有间接对象以搜索图像。您可以对这些图像进行计数,从而在PDF中存储大量图像XObjects 。如果您为所有页面添加所有Count
值,则此数字可能高于PDF中存储的Image XObject的实际数量,因为您没有考虑到某些图像可以在不同页面上重复使用
您不计算存储在内容流中的内联图片。我很有偏见。在PDF的ISO委员会中,我站在一群人的一边说“内嵌图像是邪恶的”和“内嵌图像应该死”。目前,我们没有成功摆脱内联图像,但我们引入了一些实质性的限制,应该减少PDF中符合ISO-32000-2(即将到期的PDF 2.0规范)的内联图像的使用(ab)在2016年)。
您已经发现PDF具有内嵌图像。那些是refObj == null
的图像。它们不存储为间接对象;它们以内联方式存储在页面的内容流中。根据我对内嵌图像的感受,您可以想象,因此我认为您的PDF是一个糟糕的PDF(尽管它符合ISO-32000-1)。
如果通过删除包含图像流对象的间接对象来删除Image XObjects,则必须非常小心:您确定没有损坏文档吗?因为在页面的内容流中有对Image XObject的引用。此引用指向页面/XObjects
的{{1}}条目中的条目。这个/Resources
引用带有图像字节的流对象。如果删除该间接对象而不删除引用(例如,从内容流中删除),则会破坏PDF。有些观众会忽略这些错误,但在某些时候某些工具(或某些正文)会抱怨你的PDF已损坏。
如果要删除内嵌图像,则必须解析PDF中的所有内容流:页面内容流以及Form XObject内容流。您必须重写所有这些流并确保删除所有内嵌图像。即:所有以/XObject
运算符(Begin Image)开头并以BI
运算符结束的对象(End Image)。
对于从内到外了解iTextSharp和ISO-32000-1的PDF专家来说,这是一项任务。您的问题的解决方案可能不适合StackOverflow上的应答窗口。
我是iText的原作者。从某种角度来看,iText就像一把锋利的刀。锋利的刀是一种非常好的工具,可用于许多好东西。但是,当您没有以正确的方式使用刀具时,您也可以严重割伤手指。我希望你会小心,并且你不会创建一系列损坏的PDF文件。
例如:您假设PDF中的某些文件是PNG,因为iText建议将它们存储为PNG。但是:ISO-32000-1不支持PNG,因此您认为PDF包含PNG是错误的。当我看到像你这样的问题时,我真的很担心。