正如评论中所说,pdf 格式没有任何图像字段。一些 pdf 设计器允许使用例如模拟它们。一个按钮加上一些javascript。但是由于该字段只是模拟的,因此没有图像值。这确实是您的两个文档的情况。
因此,要从源表单按钮中检索图像,我们不能获取按钮值,而是必须从按钮外观中提取图像。我们使用 itext 解析器命名空间类和一个自定义的 ImageRenderListener 渲染侦听器类来收集位图图像。
要将图像设置为目标表单按钮,此外,我们也不能简单地设置按钮值,而必须设置按钮外观。我们使用 iText AcroFields 方法 GetNewPushbuttonFromField 和 ReplacePushbuttonField 来做到这一点。
ImageRenderListener 渲染监听器类
这个渲染监听器所做的只是收集位图图像:
public class ImageRenderListener : IRenderListener
{
public List<System.Drawing.Image> Images = new List<System.Drawing.Image>();
public void BeginTextBlock()
{ }
public void EndTextBlock()
{ }
public void RenderText(TextRenderInfo renderInfo)
{ }
public void RenderImage(ImageRenderInfo renderInfo)
{
PdfImageObject imageObject = renderInfo.GetImage();
if (imageObject == null)
{
Console.WriteLine("Image {0} could not be read.", renderInfo.GetRef().Number);
}
else
{
Images.Add(imageObject.GetDrawingImage());
}
}
}
图片的Copy方法
此方法从源阅读器表单元素中检索第一张图像并将其添加到目标压模表单元素:
void Copy(PdfReader source, string sourceButton, PdfStamper target, string targetButton)
{
PdfStream xObject = (PdfStream) PdfReader.GetPdfObjectRelease(source.AcroFields.GetNormalAppearance(sourceButton));
PdfDictionary resources = xObject.GetAsDict(PdfName.RESOURCES);
ImageRenderListener strategy = new ImageRenderListener();
PdfContentStreamProcessor processor = new PdfContentStreamProcessor(strategy);
processor.ProcessContent(ContentByteUtils.GetContentBytesFromContentObject(xObject), resources);
System.Drawing.Image drawingImage = strategy.Images.First();
Image image = Image.GetInstance(drawingImage, drawingImage.RawFormat);
PushbuttonField button = target.AcroFields.GetNewPushbuttonFromField(targetButton);
button.Image = image;
target.AcroFields.ReplacePushbuttonField(targetButton, button.Field);
}
一个例子
我使用 Adobe Acrobat Reader 将图像填充到源文档中
并将此文档保存为Customer Order Form-Willi.pdf。
然后我应用了上面的复制方法:
String source = @"Customer Order Form-Willi.pdf";
String dest = @"Production Sheet.pdf";
String target = @"Production Sheet-withImage.pdf";
using (PdfReader sourceReader = new PdfReader(source))
using (PdfReader destReader = new PdfReader(dest))
using (PdfStamper targetStamper = new PdfStamper(destReader, File.Create(target), (char)0, true))
{
Copy(sourceReader, "proofImage", targetStamper, "proofImage");
}
Production Sheet-withImage.pdf中的结果:
一些警告
上面的代码非常乐观,不包含任何合理性检查。对于生产,您应该明确地使其更具防御性并检查null 值、空列表等。