Подтвердить что ты не робот

Удаление PDF невидимых объектов с помощью iTextSharp

Можно ли использовать iTextSharp для удаления из объектов документа PDF, которые не видны (или, по крайней мере, не отображаются)?

Подробнее:

1) Мой источник - это страница PDF, содержащая изображения и текст (возможно, некоторые векторные рисунки) и встроенные шрифты.

2) Существует интерфейс для создания нескольких "полей обрезки".

3) Я должен создать новый PDF файл, содержащий только то, что находится внутри полей обрезки. Все остальное должно быть удалено из результирующего документа (действительно, я могу принять контент, который находится наполовину внутри и наполовину снаружи, но это не идеал, и он не должен появляться в любом случае).

Мое решение:

Я успешно разработал решение, которое создает новые временные документы, каждый из которых содержит содержимое каждого поля обрезки (используя writer.GetImportedPage и contentByte.AddTemplate для страницы, которая точно равна размеру поля обрезки). Затем я создаю окончательный документ и повторяю процесс, используя метод AddTemplate, чтобы разместить каждую "обрезанную страницу" на последней странице.

Это решение имеет 2 больших недостатка:

  • Размер документа - [исходный размер] * [количество полей обрезки], так как вся страница там, штампована много раз! (невидимый, но он там)
  • доступ к невидимому тексту можно получить, выбрав все (CTRL + A) внутри Reader и вставленные.

Итак, я думаю, мне нужно перебирать объекты PDF, обнаруживать, видимо или нет, и удалить его. На момент написания статьи я пытаюсь использовать pdfReader.GetPdfObject.

Спасибо за помощь.

4b9b3361

Ответ 1

Если PDF файл, который вы пытаетесь, является шаблоном/предопределенным/фиксированным, вы можете удалить этот объект, вызвав RemoveField.

PdfReader pdfReader = new PdfReader(../Template_Path.pdf"));
PdfStamper pdfStamperToPopulate = new PdfStamper(pdfReader, new FileStream(outputPath, FileMode.Create));
AcroFields pdfFormFields = pdfStamperToPopulate.AcroFields;
pdfFormFields.RemoveField("fieldNameToBeRemoved");

Ответ 2

PdfReader pdfReader = new PdfReader(../Template_Path.pdf"));
PdfStamper pdfStamperToPopulate = new PdfStamper(pdfReader, new FileStream(outputPath, FileMode.Create));
AcroFields pdfFormFields = pdfStamperToPopulate.AcroFields;
pdfFormFields.RemoveField("fieldNameToBeRemoved");

Ответ 3

Да, это возможно. Вам нужно разобрать байты содержимого страницы PDF в PdfObjects, сохранить их в памяти, удалить ненужные PdfObject, создать Pdf-содержимое из PdfObject обратно в байты содержимого PDF, заменить содержимое страницы в PdfReader непосредственно перед импортом страницы через PdfWriter.

Я бы порекомендовал вам проверить это: http://habjan.blogspot.com/2013/09/proof-of-concept-converting-pdf-files.html

Образец из ссылки реализует парсинг байтов содержимого Pdf, строит обратно из PdfObjec, заменяет байты содержимого страницы PdfReader...

Ответ 4

Вот три найденных решения, если они могут помочь кому-то (используя iTextSharp, Amyuni или Tracker-Software, так как @Hetote сказал в комментариях, которые он искал другая библиотека):

Использование iTextSharp

Как ответил @martinbuberl в другом вопросе:

public static void CropDocument(string file, string oldchar, string repChar)
{
    int pageNumber = 1;
    PdfReader reader = new PdfReader(file);
    iTextSharp.text.Rectangle size = new iTextSharp.text.Rectangle(
    Globals.fX,
    Globals.fY,
    Globals.fWidth,
    Globals.fHeight);
    Document document = new Document(size);
    PdfWriter writer = PdfWriter.GetInstance(document,
    new FileStream(file.Replace(oldchar, repChar),
    FileMode.Create, FileAccess.Write));
    document.Open();
    PdfContentByte cb = writer.DirectContent;
    document.NewPage();
    PdfImportedPage page = writer.GetImportedPage(reader,
    pageNumber);
    cb.AddTemplate(page, 0, 0);
    document.Close();
}

Другой ответ @rafixwpt в его вопрос, но он не удаляет невидимые элементы, он очищает область страницы, что может повлиять на другие части страница:

static void textsharpie()
{
    string file = "C:\\testpdf.pdf";
    string oldchar = "testpdf.pdf";
    string repChar = "test.pdf";
    PdfReader reader = new PdfReader(file);
    PdfStamper stamper = new PdfStamper(reader, new FileStream(file.Replace(oldchar, repChar), FileMode.Create, FileAccess.Write));
    List<PdfCleanUpLocation> cleanUpLocations = new List<PdfCleanUpLocation>();
    cleanUpLocations.Add(new PdfCleanUpLocation(1, new iTextSharp.text.Rectangle(0f, 0f, 600f, 115f), iTextSharp.text.BaseColor.WHITE));
    PdfCleanUpProcessor cleaner = new PdfCleanUpProcessor(cleanUpLocations, stamper);
    cleaner.CleanUp();
    stamper.Close();
    reader.Close();
}

Использование Amyuni

Как ответил @yms в другом вопросе:

Метод IacDocument.GetObjectsInRectangle

Метод GetObjectsInRectangle получает все объекты, находящиеся в указанный прямоугольник.

Затем вы можете перебирать все объекты на странице и удалять те, которые вас не интересуют:

//open a pdf document
document.Open(testfile, "");
IacPage page1 = document.GetPage(1);
Amyuni.PDFCreator.IacAttribute attribute = page1.AttributeByName("Objects");

// listObj is an array list of graphic objects
System.Collections.ArrayList listobj = (System.Collections.ArrayList) attribute.Value.Cast<IacObject>();;

// listObjToKeep is an array list of graphic objects inside a rectangle
var listObjToKeep = document.GetObjectsInRectangle(0f, 0f, 600f, 115f,  IacGetRectObjectsConstants.acGetRectObjectsIntersecting).Cast<IacObject>();
foreach (IacObject pdfObj in listObj.Except(listObjToKeep))
{
   // if pdfObj is not in visible inside the rectangle then call pdfObj.Delete();
   pdfObj.Delete(false);
}

Как сказано в комментариях @yms, другое решение, использующее новый метод IacDocument.Redact в версии 5.0, также может быть использовано для удаления все объекты в указанном прямоугольнике и нарисуйте сплошной цветной прямоугольник на своем месте.

Использование SDK Tracker-Software Editor

Я не пробовал, но это кажется возможным, см. этот post.

Ответ 5

Вы пытались использовать IRenderListener? Вы можете выборочно добавлять только те элементы в новый pdf, которые попадают в области посещений, изучая объекты StartPoint и EndPoint или Area объектов TextRenderInfo или ImageRenderInfo.