только интерактивный
Проблема с этим кодом заключается в том, что вы получаете выходной PDF-файл до его завершения:
using (PdfStamper stamper = new PdfStamper(pdfReader, os, '\0', true))
{
[...]
os.WriteTo(new FileStream(outpath, FileMode.Create, FileAccess.ReadWrite));
}
Когда stamper
закрывается (здесь неявно в конце его блока using
), записываются некоторые еще не сохраненные объекты PDF, а также записываются внутренние перекрестные ссылки и трейлер файла.
Вы записываете содержимое os
в файл перед этим. Таким образом, ваш итоговый документ неполный. Adobe Reader при открытии восстанавливает его, в результате чего получается ваш исходный документ.
только изображение
Этот код сам по себе правильный, он наносит изображение на документ и правильно его сохраняет.
Ваша проблема здесь в том, что сам документ Reader-enabled, т. е. он подписан так называемой подписью прав использования. Такие подписи сообщают Adobe Reader при открытии файла, чтобы сделать доступными дополнительные функции, отображающие редактирование рассматриваемого документа.
Но при проверке подписи на документе с изображением Adobe Reader видит, что документ был изменен способом, несовместимым с правами использования, предоставленными подписью: к содержимому страницы добавлено изображение, которое не является предоставляется подписью. Таким образом, Adobe Reader аннулирует предоставленные функции, в вашем случае редактирование формы.
Удаление подписи прав использования
Одним из вариантов в этой ситуации является удаление этой подписи. В этом случае редактирование формы с помощью этой подписи больше не предоставляется. Но в более новых версиях Adobe Reader (начиная с версии XI, если я правильно помню) редактирование формы было предоставлено всем документам по умолчанию! В вашем случае эта функция удалена из-за недействительной подписи!
Это можно сделать следующим образом:
using (Stream output = new FileStream(outpath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
using (PdfReader reader = new PdfReader(inpath))
using (var stamper = new PdfStamper(reader, output))
{
reader.RemoveUsageRights();
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(stamp);
image.SetAbsolutePosition(0, 0);
PdfTemplate template = PdfTemplate.CreateTemplate(stamper.Writer, image.Width, image.Height);
template.AddImage(image);
stamper.GetOverContent(1).AddTemplate(template, 150, 200, true);
}
Теперь вы можете редактировать PDF-файл с изображением в более новых версиях Adobe Readers.
К сожалению, при сохранении документа возникает ошибка. Я не знаю, связаны ли они с тем фактом, что исходный документ частично недействителен (Adobe Preflight жалуется на ряд проблем, в первую очередь на использование неопределенного имени кодировки Win1251Encoding) или что-то иначе сломается.
Удаление подписи прав использования в режиме добавления
Работая в режиме добавления, мы должны вручную удалить подпись прав использования. На самом деле мы удалим весь словарь Perms из Каталога:
using (Stream output = new FileStream(outpath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
using (PdfReader reader = new PdfReader(inpath))
using (var stamper = new PdfStamper(reader, output, '\0', true))
{
reader.Catalog.Remove(PdfName.PERMS);
stamper.MarkUsed(reader.Catalog);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(stamp);
image.SetAbsolutePosition(0, 0);
PdfTemplate template = PdfTemplate.CreateTemplate(stamper.Writer, image.Width, image.Height);
template.AddImage(image);
stamper.GetOverContent(1).AddTemplate(template, 150, 200, true);
}
Теперь можно отредактировать форму и сохранить файл (по крайней мере я могу в Adobe Reader DC).
PS: правильные координаты
В комментарии ОП поделился другим PDF-файлом и заявил, что он
для другого файла невозможно разместить картинку на странице с альбомной ориентацией.
В коде OP действительно есть проблема:
stamper.GetOverContent(1).AddTemplate(template, 150, 200, true);
Фиксированные координаты 150, 200
являются признаком того, что OP предполагает, что нижний левый угол страницы является источником 0, 0
системы координат. Хотя это часто имеет место, это не обязательно верно. Всегда нужно принимать во внимание CropBox (по умолчанию это MediaBox), то есть для кода OP:
Rectangle cropBox = reader.GetCropBox(1);
stamper.GetOverContent(1).AddTemplate(template, cropBox.Left + 150, cropBox.Bottom + 200, true);
библиотека принимает вращение не правильно, но дает 0 градусов.
Но это правильно! Ваш образец PDF-файла несколько особенный, поскольку в нем используется прямоугольник без поворота для альбомной ориентации и повернутый прямоугольник для портретной ориентации.
person
mkl
schedule
14.01.2016