当文件在印刷厂光栅化时,iTextSharp 旋转的 PDF 页面恢复方向
iTextSharp rotated PDF page reverts orientation when file is rasterized at print house
我正在使用 iTextSharp 创建一个由现有 PDF 集合组成的 PDF,其中一些包含的 PDF 是横向的,需要旋转。所以,我执行以下操作:
private static void AdjustRotationIfNeeded(PdfImportedPage pdfImportedPage, PdfReader reader, int documentPage)
{
float width = pdfImportedPage.Width;
float height = pdfImportedPage.Height;
if (pdfImportedPage.Rotation != 0)
{
PdfDictionary pageDict = reader.GetPageN(documentPage);
pageDict.Put(PdfName.ROTATE, new PdfNumber(0));
}
if (width > height)
{
PdfDictionary pageDict = reader.GetPageN(documentPage);
pageDict.Put(PdfName.ROTATE, new PdfNumber(270));
}
}
效果很好。如果需要,包含的 PDF 会旋转为纵向。 PDF 在我的本地打印机上打印正确。
此文件已发送至履行机构,不幸的是,包含景观的文件在经过打印机和光栅化过程时无法正确打印。他们使用 Kodak (Creo) NexRip 11.01 或 Kodak (Creo) Prinergy 6.1。机器。履行之家的建议是:"generate a new PDF file after we rotate pages or make any changes to a PDF. It is as easy as exporting out to a PostScript and distilling back to a PDF."
我知道 iTextSharp 不支持 PostScript。 iTextSharp 是否有另一种方法可以旋转包含的 PDF 以在光栅化时保持方向?
首先让我向您保证,更改页面字典中的旋转是实现您想要的目标的正确过程。据我所见,您的代码没有任何问题。你做对了。
不幸的是,您面对的是您无法控制的第三方产品不做正确的事情。如何解决?
我写了一个例子叫IncorrectExample。我这样命名它是因为我不希望它在与您不同的上下文中使用。您可以安全地忽略我添加的所有警告:它们不适合您。此示例非常针对您的问题。
请尝试以下代码:
public void manipulatePdf(String src, String dest)
throws IOException, DocumentException {
// Creating a reader
PdfReader reader = new PdfReader(src);
// step 1
Rectangle pagesize = getPageSize(reader, 1);
Document document = new Document(pagesize);
// step 2
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(dest));
// step 3
document.open();
// step 4
PdfContentByte cb = writer.getDirectContent();
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
pagesize = getPageSize(reader, i);
document.setPageSize(pagesize);
document.newPage();
PdfImportedPage page = writer.getImportedPage(reader, i);
if (isPortrait(reader, i)) {
cb.addTemplate(page, 0, 0);
}
else {
cb.addTemplate(page, 0, 1, -1, 0, pagesize.getWidth(), 0);
}
}
// step 4
document.close();
reader.close();
}
public Rectangle getPageSize(PdfReader reader, int pagenumber) {
Rectangle pagesize = reader.getPageSizeWithRotation(pagenumber);
return new Rectangle(
Math.min(pagesize.getWidth(), pagesize.getHeight()),
Math.max(pagesize.getWidth(), pagesize.getHeight()));
}
public boolean isPortrait(PdfReader reader, int pagenumber) {
Rectangle pagesize = reader.getPageSize(pagenumber);
return pagesize.getHeight() > pagesize.getWidth();
}
我以pages.pdf文件为例。这个文件的特殊之处在于它有两个以不同方式创建的横向页面:
- 一个页面是宽度小于高度的页面(听起来像纵向页面),但是由于页面字典中添加了
/Rotate
值 90
, 它是横向显示的。
- 另一个页面没有旋转,但它的高度小于宽度。
在我的示例中,我使用 类 Document
和 PdfWriter
创建原始文档的副本。这是错误的一般,因为它丢弃了所有交互。我应该改用 PdfStamper
或 PdfCopy
,但在您的特定情况下 是正确的 因为您不需要交互性:PDF 的最终目的是待打印。
使用 Document
,我使用新 Rectangle
创建新页面,该新页面使用现有页面尺寸的最小值作为宽度,最大值作为高度。这样,页面将始终为纵向。请注意,我使用方法 getPageSizeWithRotation()
来确保获得正确的宽度和高度,同时考虑到任何可能的旋转。
然后我在作者的直接内容上加一个PdfImportedPage
。我使用 isPortrait()
方法来确定是否需要旋转页面。观察 isPortrait()
方法查看页面大小 而没有 考虑旋转。如果我们确实考虑了旋转,我们会旋转不需要旋转的页面。
可以在此处找到生成的 PDF:pages_changed.pdf
如您所见,一些信息丢失了:最后一页上有一个注释:它不见了。为原始文档定义了特定的查看器首选项:它们已经消失了。但这在您的具体情况下应该无关紧要,因为对您来说重要的是页面打印正确。
我正在使用 iTextSharp 创建一个由现有 PDF 集合组成的 PDF,其中一些包含的 PDF 是横向的,需要旋转。所以,我执行以下操作:
private static void AdjustRotationIfNeeded(PdfImportedPage pdfImportedPage, PdfReader reader, int documentPage)
{
float width = pdfImportedPage.Width;
float height = pdfImportedPage.Height;
if (pdfImportedPage.Rotation != 0)
{
PdfDictionary pageDict = reader.GetPageN(documentPage);
pageDict.Put(PdfName.ROTATE, new PdfNumber(0));
}
if (width > height)
{
PdfDictionary pageDict = reader.GetPageN(documentPage);
pageDict.Put(PdfName.ROTATE, new PdfNumber(270));
}
}
效果很好。如果需要,包含的 PDF 会旋转为纵向。 PDF 在我的本地打印机上打印正确。
此文件已发送至履行机构,不幸的是,包含景观的文件在经过打印机和光栅化过程时无法正确打印。他们使用 Kodak (Creo) NexRip 11.01 或 Kodak (Creo) Prinergy 6.1。机器。履行之家的建议是:"generate a new PDF file after we rotate pages or make any changes to a PDF. It is as easy as exporting out to a PostScript and distilling back to a PDF."
我知道 iTextSharp 不支持 PostScript。 iTextSharp 是否有另一种方法可以旋转包含的 PDF 以在光栅化时保持方向?
首先让我向您保证,更改页面字典中的旋转是实现您想要的目标的正确过程。据我所见,您的代码没有任何问题。你做对了。
不幸的是,您面对的是您无法控制的第三方产品不做正确的事情。如何解决?
我写了一个例子叫IncorrectExample。我这样命名它是因为我不希望它在与您不同的上下文中使用。您可以安全地忽略我添加的所有警告:它们不适合您。此示例非常针对您的问题。
请尝试以下代码:
public void manipulatePdf(String src, String dest)
throws IOException, DocumentException {
// Creating a reader
PdfReader reader = new PdfReader(src);
// step 1
Rectangle pagesize = getPageSize(reader, 1);
Document document = new Document(pagesize);
// step 2
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(dest));
// step 3
document.open();
// step 4
PdfContentByte cb = writer.getDirectContent();
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
pagesize = getPageSize(reader, i);
document.setPageSize(pagesize);
document.newPage();
PdfImportedPage page = writer.getImportedPage(reader, i);
if (isPortrait(reader, i)) {
cb.addTemplate(page, 0, 0);
}
else {
cb.addTemplate(page, 0, 1, -1, 0, pagesize.getWidth(), 0);
}
}
// step 4
document.close();
reader.close();
}
public Rectangle getPageSize(PdfReader reader, int pagenumber) {
Rectangle pagesize = reader.getPageSizeWithRotation(pagenumber);
return new Rectangle(
Math.min(pagesize.getWidth(), pagesize.getHeight()),
Math.max(pagesize.getWidth(), pagesize.getHeight()));
}
public boolean isPortrait(PdfReader reader, int pagenumber) {
Rectangle pagesize = reader.getPageSize(pagenumber);
return pagesize.getHeight() > pagesize.getWidth();
}
我以pages.pdf文件为例。这个文件的特殊之处在于它有两个以不同方式创建的横向页面:
- 一个页面是宽度小于高度的页面(听起来像纵向页面),但是由于页面字典中添加了
/Rotate
值90
, 它是横向显示的。 - 另一个页面没有旋转,但它的高度小于宽度。
在我的示例中,我使用 类 Document
和 PdfWriter
创建原始文档的副本。这是错误的一般,因为它丢弃了所有交互。我应该改用 PdfStamper
或 PdfCopy
,但在您的特定情况下 是正确的 因为您不需要交互性:PDF 的最终目的是待打印。
使用 Document
,我使用新 Rectangle
创建新页面,该新页面使用现有页面尺寸的最小值作为宽度,最大值作为高度。这样,页面将始终为纵向。请注意,我使用方法 getPageSizeWithRotation()
来确保获得正确的宽度和高度,同时考虑到任何可能的旋转。
然后我在作者的直接内容上加一个PdfImportedPage
。我使用 isPortrait()
方法来确定是否需要旋转页面。观察 isPortrait()
方法查看页面大小 而没有 考虑旋转。如果我们确实考虑了旋转,我们会旋转不需要旋转的页面。
可以在此处找到生成的 PDF:pages_changed.pdf
如您所见,一些信息丢失了:最后一页上有一个注释:它不见了。为原始文档定义了特定的查看器首选项:它们已经消失了。但这在您的具体情况下应该无关紧要,因为对您来说重要的是页面打印正确。