即使form扁平化属性为false,它也会被扁平化
本文关键字:扁平化 false form 属性 即使 | 更新日期: 2023-09-27 18:03:33
我有以下方法,应该在给定坐标的pdf文件上盖章图像,并返回它与层仍然分开,即不平坦,我设置了formflating属性,但它不起作用。
经过一些实验,我发现当我调用getPdfLayers方法时,文件不会被扁平,为什么会这样?
public static byte[] StampLayer(System.Drawing.Image image, int x, int y, string layername)
{
var iImage = iTextSharp.text.Image.GetInstance(image, ImageFormat.Tiff);
var reader = new PdfReader(_pdfFile);
using (var ms = new MemoryStream())
{
using (var stamper = new PdfStamper(reader, ms))
{
//Don't delete otherwise the stamper flattens the layers
var layers = stamper.GetPdfLayers();
stamper.FormFlattening = false;
var logoLayer = new PdfLayer(layername, stamper.Writer);
PdfContentByte cb = stamper.GetUnderContent(1);
cb.BeginLayer(logoLayer);
//300dpi
iImage.ScalePercent(24f);
iImage.SetAbsolutePosition(x, y);
cb.AddImage(iImage);
cb.EndLayer();
stamper.Close();
return (ms.GetBuffer());
}
}
}
iTextSharp版本为:5.5.6
我试过png和jpg的图片,结果是一样的。
看起来您在iText(Sharp)中发现了一个bug。但是你的代码中还有一个额外的弱点。
错误
PdfStamperImp
(stamper.Writer
类)由PdfWriter
衍生而来。PdfWriter
保存了它写入的PDF的层的集合:
protected Dictionary<IPdfOCG, object> documentOCG = new Dictionary<IPdfOCG,object>();
PdfStamperImp
只惰性地用文档的现有层初始化这个成员,例如在它的方法GetPdfLayers
:
virtual public Dictionary<string,PdfLayer> GetPdfLayers()
{
if (documentOCG.Count == 0)
{
ReadOCProperties();
}
...
正如你所看到的,它使用documentOCG
字典的计数作为初始化是否已经发生的指示器。
不幸的是,
var logoLayer = new PdfLayer(layername, stamper.Writer);
打破了这种惰性初始化方案:它执行
writer.RegisterLayer(this);
和RegisterLayer
在PdfWriter
中定义
documentOCG[layer] = null;
因此,在new PdfLayer(layername, stamper.Writer)
之后,documentOCG.Count
大于0,这防止了惰性层初始化,因此在冲压期间有效地删除了重要的层信息,除非初始化之前已经发生。
//Don't delete otherwise the stamper flattens the layers
var layers = stamper.GetPdfLayers();
本质上强制初始化在 PdfLayer
构造函数被调用之前发生。
这个bug可以通过在PdfStamperImp
中重写RegisterLayer
来修复(当然它必须是虚拟的);重写必须首先触发惰性初始化本身。实际上,延迟初始化应该使用一个独立的标志,并检查字典计数作为完整性检查。
iText中存在一个模拟错误,可以使用StampInLayer.java复制。
代码中的问题
你回来
return (ms.GetBuffer());
这是完全错误的:缓冲区通常比实际文件大,也就是说,您返回的PDF具有长尾的垃圾字节。使用
return (ms.ToArray());
。
误解在你的问题和你的代码中,你假设你的问题是形式变平并试图干预。不过,表单变平与你的问题无关。表单扁平化是关于将AcroForm表单字段值扁平化(合并到内容中),例如文本字段或复选框。