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