Как изменить тримбокс PDF-файла с помощью itextsharp - PullRequest
2 голосов
/ 28 января 2011

У меня есть готовый PDF, и мне нужно изменить trimbox, bleedbox с SetBoxSize и использовать setPDFXConformance.Есть ли способ сделать это?

Я пробовал с stamper.Writer, но мне все равно, что я там установил

2011.02.01.
Мыпроверил его с помощью Acrobat Pro, и он сказал, что trimbox не был определен.Кажется, что методы / свойства автора штампа не влияют на полученный pdf.Вот исходные файлы и файлы результатов: http://stemaweb.hu/pdfs.zip

мой код:

PdfReader reader = new PdfReader(@"c:\source.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileStream(@"c:\result.pdf", FileMode.Create));
stamper.Writer.SetPageSize(PageSize.A4);
stamper.Writer.PDFXConformance = PdfWriter.PDFX32002;
stamper.Writer.SetBoxSize("trim", new iTextSharp.text.Rectangle(20, 20, 100, 100));
PdfContentByte cb = stamper.GetOverContent(1);
/*drawing*/
stamper.Close();

Поскольку поля не видны, я попытался изменить размер страницы с помощью программы записи, нотоже ничего не делал.

1 Ответ

2 голосов
/ 28 января 2011

SetPDFXConformance не превратит «нормальный» PDF в PDF / X pdf.SetPDFXConformance действительно предназначен только для генерации документов, поэтому iText создает исключение, если вы делаете что-то явно не так, как указано в спецификации.

«ему все равно, что я там установил».Коробки обрезки и обрезки - это не то, что вы можете увидеть визуально в Reader.Как вы их тестируете?

Не могли бы вы опубликовать код и ссылку на ваш выходной PDF?


Ах.Вы используете stamper.Writer.В этом случае это не так хорошо работает.Весь уровень страницы, хорошо поддерживаемые действия через PdfStamper, будет принимать номер страницы или PdfDictionary страницы в качестве аргумента.SetBoxSize просто принимает строку и прямоугольник, так что это ваша подсказка.

Переход "под капот", как вы есть, по умолчанию возвращается к PdfWriter.setBoxSize ..., который предназначен только для создания PDF-файлов, а не для изменениясуществующая страница.

Итак: Вам нужно использовать низкоуровневые объекты PDF, чтобы внести необходимые изменения.Нет проблем:

for (int i = 1; i <= myReader.getNumberOfPages(); ++i) {
  PdfDictionary pageDict = myREADER_YES_READER.getPageN(i);

  PdfRectangle newBox = new PdfRectangle( 20, 20, 100, 100 );
  pageDict.put(PdfName.TRIMBOX, newBox);

  newBox = new PdfRectangle( PageSize.A4 );
  pageDict.put(PdfName.MEDIABOX, newBox );
}

/* drawing */

stamper.close();

Что касается соответствия PDFX32002, я думаю, что вам придется заняться дайвингом кода, чтобы выяснить, что именно нужно.Writer.PDFXConformance - это еще один аспект Writer, который работает только при создании PDF-файла, а не при изменении существующего.

Хорошая новость заключается в том, что PdfXConformanceImp является открытым классом.Плохая новость заключается в том, что он используется только внутри PdfWriter и PdfContentByte ... эй.Вы получаете некоторые изменения в поведении вашего нынешнего кода (просто недостаточно).В частности, если вы попробуете что-то, что не разрешено в этом PdfContentByte, вы получите PdfXConformanceException с сообщением, описывающим нарушение, которое вы нарушили.Например, попытка добавить необязательную группу содержимого (слой) приведет к выбросу.

А-а.Это не так плохо.МОЖЕТ БЫТЬ.Попробуйте это:

PDFXConformanceImp pdfx = new PDFXConformanceImp();
pdfx.setConformance(PdfWriter.PDFX32002);

pdfx.commpleteInfoDictionary(stamper.Writer.getInfo());
pdfx.completeExtraCatalog(stamper.Writer.getExtraCatalog());

stamper.close();

Если вы уроните stamper.Writer.PDFXConformance = PdfWriter.PDFX32002;, вы не получите исключений, когда сделаете что-то запрещенное в вашем contentByte.Кроме этого, я не думаю, что это будет иметь значение.

Хмм .. Это не все решение.OutputIntents из extraCatalog также объединяется с основным каталогом.Возможно, это сработает:

//replace the completeExtraCatalog call above with this
pdfx.completeExtraCatalog(myReader.getCatalog());

Я желаю вам удачи.

...