Как уже говорилось в комментарии, в формате 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());
}
}
}
A 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
значений, пустых списков и т. Д.