我搜索过并找不到问题的答案。我已经在我的代码中尝试了许多不同的方法,但我已经碰壁了,我不确定从哪里开始。我似乎想要做与这两个线程相同的事情:
Trying to insert an image into a pdf in c#
Add image in an existing PDF with itextsharp
它们非常相似,答案是一样的。但是,当我使用该确切代码时,结果是没有图像的PDF。这是我的代码:
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
var pdfReader = new PdfReader(existingFileStream);
var stamper = new PdfStamper(pdfReader, newFileStream, '\0', true);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (var field in form.Fields)
{
if (field.Key == "form1[0].ec_Bldg_Photo_1[0].ImageField2[0]")
{
PushbuttonField imageField = form.GetNewPushbuttonFromField(field.Key);
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.IconReference = null;
imageField.ProportionalIcon = true;
imageField.Image = Image.GetInstance(@"PATH_TO_IMAGE\front.jpg");
form.ReplacePushbuttonField(field.Key, imageField.Field);
}
}
stamper.FormFlattening = false;
stamper.Close();
pdfReader.Close();
}
我试图排除所有显而易见的事情。我的图像路径是正确的,当我读取现有的PDF字段并获取字段类型时,该字段确实是一个PushbuttonField。如果我在Adobe Reader中打开PDF并单击图像的占位符,它允许我从我的PC中选择一个文件。当我将图像放入文件,保存,然后读取该PDF时,我可以将我的代码更改为:
imageField.ProportionalIcon = false;
现在突然间,图像在保存的副本上被拉伸。所以我看到它正在改变这部分,但这是我在Adobe Reader中手动输入图像的时候。在我在Adobe Reader中设置该图像并且显示正确后,我在该领域阅读时,我看到了一些有趣的事情。 field.Image属性为IS NULL,field.IconReference为NOT NULL。当我使用原始代码尝试插入图像时,它是相反的,其中Image为NOT NULL但IconReference为空
非常感谢任何帮助,谢谢!!
编辑1:好的,所以我第一次没有看到它,但我回去检查得更彻底,我确实找到了钥匙。这是:
答案 0 :(得分:1)
这里有几件事情在发挥作用。
使用权利
PDF使用Adobe拥有的私钥进行数字签名。
你可以在这里使用RUPS看到这一点(在屏幕截图中你没有足够深):
这有两个含义:
此功能已弃用(甚至已删除)PDF 2.0。随着Adobe Reader以外的PDF查看器的出现,它的旧技术已经过时。
我的建议:删除使用权限以避免破坏签名。请参阅常见问题解答条目"为什么我会收到错误消息,说明"扩展功能的使用已不再可用"?" iText 7 / iText 5
这是iText 7代码:
public void removeUsageRights(PdfDocument pdfDoc) {
PdfDictionary perms = pdfDoc.getCatalog().getPdfObject().getAsDictionary(PdfName.Perms);
if (perms == null) {
return;
}
perms.remove(new PdfName("UR"));
perms.remove(PdfName.UR3);
if (perms.size() == 0) {
pdfDoc.getCatalog().remove(PdfName.Perms);
}
}
这是iText 5代码:
PdfReader reader = new PdfReader(old_file);
if (reader.hasUsageRights()) {
reader.removeUsageRights();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new_file));
stamper.close();
}
reader.close();
这是iText 5的答案。
混合形式:
如果单击/AcroForm
条目,您会看到:
有一个/Fields
数组,其中包含对字段字典的引用,这些字典也是窗口小部件注释。这意味着该文档内部有一个AcroForm表单。但是,还有一个带有一系列XML片段的/XFA
条目。这意味着该文档内部有一个XFA表单。
换句话说:在内部添加两次相同的表单描述。您正在更改一个表单中的按钮(AcroForm部分),但不会更改另一个表单(XFA表单),这会导致不一致。
XFA已在PDF 2.0中弃用,因为没有多家供应商支持该技术。面对使用弃用技术的表单会感到沮丧。
我的建议:我会删除XFA部分。请参阅常见问题条目"删除XFA是否安全?" iText 5 / iText 7
在iText 5中,删除XFA的方式如下:
AcroFields form = stamper.getAcroFields();
form.removeXfa();
重要提示:我的建议是从PDF中删除所有已弃用的功能,但如果政府希望该功能存在,那么您运气不好。在这种情况下,您将需要使用Adobe软件来处理表单。如果是这种情况,你可以向政府抱怨他们的要求会导致事实上的供应商锁定。顺便说一句:iText软件也是供应商。它是一家开源公司,根据AGPL许可证提供开源软件。 AGPL许可证允许在某些情况下免费使用(请参阅How do I make sure my software complies with AGPL: How can I use iText for free?)如果您不满足这些要求,则必须购买商业许可才能使用iText。