C # iTextSharp - копирование изображения из одного поля изображения в другое - PullRequest
0 голосов
/ 26 июня 2018

Я создал 2 заполняемых формой PDF-файла, один для использования в качестве формы заказа клиента, а другой для собственного использования в качестве рабочего листа. Каждый из PDF-файлов имеет идентичные поля (одинаковые имя и тип поля для каждого). Я написал приложение, которое (среди прочего) использует iTextSharp для чтения всех полей в данной форме заказа клиента, создает новый рабочий лист и заполняет все данные из формы заказа. Это все работает гладко для полей текста и даты (строковые данные). Однако в каждом файле PDF есть одно поле изображения, и мне нужно взять изображение из поля изображения в форме заказа и скопировать его в поле изображения на рабочем листе. Вот где я зацикливаюсь.

Я могу использовать pr.Acrofields.GetFieldItem("imageFieldName");, чтобы получить изображение как Acrofields.item объект, но я не могу заставить iTextSharp позволить мне поместить это в поле изображения, используя метод, подобный PdfStamper.Acrofields.SetField(), так как он будет только взять строку.

Возможно, есть ли способ взять эти данные изображения и сохранить их как временный файл .jpg или .bmp, а затем вставить их в поле изображения рабочего листа? Или я все об этом говорю не так?

1 Ответ

0 голосов
/ 30 июня 2018

Как уже говорилось в комментарии, в формате 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

Screen shot customer order form

и сохранил этот документ как 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:

enter image description here

Несколько слов предупреждения

Код выше очень оптимистичен и не содержит проверок достоверности. Для производства вы должны сделать его более оборонительным и проверить наличие null значений, пустых списков и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...