Itext 当使用PdfStamper将图像放置在“过度内容”上时,以后如何才能找到它?

Itext 当使用PdfStamper将图像放置在“过度内容”上时,以后如何才能找到它?,itext,Itext,当条形码图像以这种方式使用压模放置在pdf上时: PdfContentByte page = stamper.GetOverContent(i); image.SetAbsolutePosition(x, y); page.AddImage(image); 在查看器中呈现PDF时,它会正确显示,但下面的代码找不到它()。代码根本无法识别它是否存在。该代码发现一个图像放置在PDF中的AcROAT PRO席,但不是一个以上的方式添加。 在iTextSharp中将条形码图像放置在pdf上

当条形码图像以这种方式使用压模放置在pdf上时:

  PdfContentByte page = stamper.GetOverContent(i);
  image.SetAbsolutePosition(x, y);
  page.AddImage(image);
在查看器中呈现PDF时,它会正确显示,但下面的代码找不到它()。代码根本无法识别它是否存在。该代码发现一个图像放置在PDF中的AcROAT PRO席,但不是一个以上的方式添加。 在iTextSharp中将条形码图像放置在pdf上的正确方法是什么,以便将图像包含在PdfDictionary中?需要更改什么,上面的代码还是下面的代码

 for (int pageNumber = 1; pageNumber <= pdf.NumberOfPages; pageNumber++)
    {
         PdfDictionary pg = pdf.GetPageN(pageNumber);                  
         PdfObject obj = FindImageInPDFDictionary(pg);
         if (obj != null)
             {
                int XrefIndex = Convert.ToInt32(((PRIndirectReference)obj).Number.ToString(System.Globalization.CultureInfo.InvariantCulture));
                 PdfObject pdfObj = pdf.GetPdfObject(XrefIndex);
                 PdfStream pdfStrem = (PdfStream)pdfObj;
                 byte[] bytes = PdfReader.GetStreamBytesRaw((PRStream)pdfStrem);
                   if ((bytes != null))
                        {
                            using (System.IO.MemoryStream memStream = new System.IO.MemoryStream(bytes))
                            {
                                memStream.Position = 0;
                                System.Drawing.Image img = System.Drawing.Image.FromStream(memStream);
                     // now we have an image and can examine it
                     // to see if it is a barcode               
                            }

                    }
             }

        }

for(int pageNumber=1;pageNumber首先,iText
图像
对象不一定是位图图像,但也可以是仅包含矢量图形的表单xobject的包装。另一方面,提取代码只考虑位图图像

然而,在本例中,结果证明该图像确实是位图图像


iText将图像添加到
过内容
的方式没有什么特别之处,问题在于您所指问题的
findimageinpdfddictionary
方法:

private static PdfObject FindImageInPDFDictionary(PdfDictionary pg) {
    PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(pg.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 type = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));

                //image at the root of the pdf
                if (PdfName.IMAGE.Equals(type)) {
                    return obj;
                }// image inside a form
                else if (PdfName.FORM.Equals(type)) {
                    return FindImageInPDFDictionary(tg);
                } //image inside a group
                else if (PdfName.GROUP.Equals(type)) {
                    return FindImageInPDFDictionary(tg);
                }
            }
        }
    }
    return null;
}
它的缺陷不止一个:

  • 它只考虑
    pg
    字典资源中的第一个图像表单xobject,因为它在任何情况下都会立即返回,而不管后两种情况中的任何一种递归调用是否返回非
    null
    结果
  • 撇开上面的问题不谈,它只检查页面资源以及包含的表单XObject和Group的资源,而不检查其他内容,
    • 它不会检查它找到的图像资源是否在页面上实际使用,因此它可能返回一个根本不在页面上的图像
    • 它忽略内容流中包含的内联图像,以及
    • 它忽略模式或类型3字体中包含的图像
  • 它忽略找到的图像是否有遮罩。有时遮罩包含生成图像的主要信息,而基础图像仅确定颜色;特别是墨水签名图像通常包含遮罩中的笔路径,而整个基础图像都充满了墨水颜色
  • 它不能在每页返回多个图像
此外,如果在该答案中使用

PdfDictionary pg = pdf.GetPageN(pageNumber);

// recursively search pages, forms and groups for images.
PdfObject obj = FindImageInPDFDictionary(pg);
然后,只检查与页面对象直接关联的资源,但也可以从页面树中的祖先节点继承资源


您应该改用iText解析框架,参见to或其变体(有一个
MyImageRenderListener
类经常被引用)

  • 它通过回调返回它的所有发现,而不仅仅是每页一个
  • 它不忽略它所考虑的一些图像;
  • 它扫描内容流,因此,查找内联图像和实际使用的资源
  • 它返回图像的掩码(如果适用)
  • 作为奖励,它返回图像使用的位置和变换

但它并不完美:特别是它不扫描模式和类型3字体的图像(但解析框架允许尝试提取类型3字体用作文本),它也不查看继承的资源。

您所指问题的公认答案中的
findimageinpdfddictionary
方法在许多方面都有缺陷。您应该使用iText解析框架,请参见。也就是说,您添加的是真正的位图图像吗?毕竟,iText可以包装其他图像还有
图像
。@mkl:谢谢,我会看看答案。条形码实际上是一个iTextSharp.text.Image对象。
iTextSharp.text.Image
对象可以包含很多不同的东西。其中包括位图图像,还有其他实体。那么,你的
图像
包含什么?你提到了条形码。这很可能是一个由矢量数据组成的图像,而不是光栅数据。矢量数据存储为PDF中的form XObject;虽然您使用
image
类,但从PDF的角度来看,它不被视为图像。PDF中的图像存储为image XObject。iText中用于从PDF中提取图像的解析器框架只查找图像XObject,不查找表单XObject。