使用 iTextSharp 在 C# 中旋转 PDF
Posted
技术标签:
【中文标题】使用 iTextSharp 在 C# 中旋转 PDF【英文标题】:Rotating PDF in C# using iTextSharp 【发布时间】:2011-04-04 11:46:44 【问题描述】:我正在使用以下函数将 pdf 一分为二。
虽然它正在拆分 pdf,但内容却是颠倒的。我如何将它旋转 180 度。
请帮忙。下面是相同的代码
private static void ExtractPages(string inputFile, string outputFile,
int start, int end)
// get input document
PdfReader inputPdf = new PdfReader(inputFile);
// retrieve the total number of pages
int pageCount = inputPdf.NumberOfPages;
if (end < start || end > pageCount)
end = pageCount;
// load the input document
Document inputDoc =
new Document(inputPdf.GetPageSizeWithRotation(1));
// create the filestream
using (FileStream fs = new FileStream(outputFile, FileMode.Create))
// create the output writer
PdfWriter outputWriter = PdfWriter.GetInstance(inputDoc, fs);
inputDoc.Open();
PdfContentByte cb1 = outputWriter.DirectContent;
// copy pages from input to output document
for (int i = start; i <= end; i++)
inputDoc.SetPageSize(inputPdf.GetPageSizeWithRotation(1));
inputDoc.NewPage();
PdfImportedPage page =
outputWriter.GetImportedPage(inputPdf, i);
int rotation = inputPdf.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
cb1.AddTemplate(page, 0, -1f, 1f, 0, 0,
inputPdf.GetPageSizeWithRotation(i).Height);
else
cb1.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
inputDoc.Close();
【问题讨论】:
【参考方案1】:我发现上述答案在所有 4 个主要旋转中都没有正确旋转。
以下是我正确处理 0、90、180 和 270 的代码。这已经通过在每个方向旋转的 PDF 进行了测试。
var pageRotation = reader.GetPageRotation(currentPageIndex);
var pageWidth = reader.GetPageSizeWithRotation(currentPageIndex).Width;
var pageHeight = reader.GetPageSizeWithRotation(currentPageIndex).Height;
switch (pageRotation)
case 0:
writer.DirectContent.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0);
break;
case 90:
writer.DirectContent.AddTemplate(importedPage, 0, -1f, 1f, 0, 0, pageHeight);
break;
case 180:
writer.DirectContent.AddTemplate(importedPage, -1f, 0, 0, -1f, pageWidth, pageHeight);
break;
case 270:
writer.DirectContent.AddTemplate(importedPage, 0, 1f, -1f, 0, pageWidth, 0);
break;
default:
throw new InvalidOperationException(string.Format("Unexpected page rotation: [0].", pageRotation));
【讨论】:
+1: 显然case 0:
可以缩短为 writer.DirectContent.AddTemplate(importedPage, 0, 0);
您的回答刚刚帮助我解决了将现有 PDF 再旋转 90、180 或 270 度的问题 :)如果这些参数记录在某处,那就太好了,因为我收集它们是矩阵变换(?)。非常感谢。
已旋转页面的旋转还有一个问题。我使用了您的答案,并添加了一个带有附加页面大小/旋转操作的答案,以允许旋转已旋转的页面。【参考方案2】:
你应该试试这个。它对我有用:
if (rotation == 90 || rotation == 270)
if (rotation == 90)
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(pagenumber).Height);
if (rotation == 270)
cb.AddTemplate(page, 0, 1.0F, -1.0F, 0, reader.GetPageSizeWithRotation(pagenumber).Width, 0);
else
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
【讨论】:
【参考方案3】:@TimS
' 的答案非常接近完美,并为AddTemplate
提供了正确的参数,但我需要添加一些内容以允许页面 的 PDF 旋转 90、180、270已经有 0、90、180 或 270 的旋转:
假设RotateFlipType rotateFlipType
的参数被传递给函数以指定旋转(来自 GDI+ RotateFlip 调用的方便枚举):
iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
iTextSharp.text.pdf.PdfImportedPage page;
int rotation;
int i = 0;
while (i < pageCount)
i++;
var pageSize = reader.GetPageSizeWithRotation(i);
// Pull in the page from the reader
page = writer.GetImportedPage(reader, i);
// Get current page rotation in degrees
rotation = pageSize.Rotation;
// Default to the current page size
iTextSharp.text.Rectangle newPageSize = null;
// Apply our additional requested rotation (switch height and width as required)
switch (rotateFlipType)
case RotateFlipType.RotateNoneFlipNone:
newPageSize = new iTextSharp.text.Rectangle(pageSize);
break;
case RotateFlipType.Rotate90FlipNone:
rotation += 90;
newPageSize = new iTextSharp.text.Rectangle(pageSize.Height, pageSize.Width, rotation);
break;
case RotateFlipType.Rotate180FlipNone:
rotation += 180;
newPageSize = new iTextSharp.text.Rectangle(pageSize.Width, pageSize.Height, rotation);
break;
case RotateFlipType.Rotate270FlipNone:
rotation += 270;
newPageSize = new iTextSharp.text.Rectangle(pageSize.Height, pageSize.Width, rotation);
break;
// Cap rotation into the 0-359 range for subsequent check
rotation %= 360;
document.SetPageSize(newPageSize);
document.NewPage();
// based on the rotation write out the page dimensions
switch (rotation)
case 0:
cb.AddTemplate(page, 0, 0);
break;
case 90:
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, newPageSize.Height);
break;
case 180:
cb.AddTemplate(page, -1f, 0, 0, -1f, newPageSize.Width, newPageSize.Height);
break;
case 270:
cb.AddTemplate(page, 0, 1f, -1f, 0, newPageSize.Width, 0);
break;
default:
throw new System.Exception(string.Format("Unexpected rotation of 0 degrees", rotation));
break;
希望这将有助于其他希望纠正传入 PDF 旋转的人。我花了 2 天时间来完善它。
【讨论】:
你的代码就像一个魅力。非常感谢。你拯救了我的一天。 @RolandDeschain:很高兴它有帮助:)【参考方案4】:我试过你的代码,它对我来说很好;分页保持原来的方向。
解决方法可能是将页面显式旋转 180 度。
替换:
cb1.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
与:
cb1.AddTemplate(page, -1f, 0, 0, -1f,
inputPdf.GetPageSizeWithRotation(i).Width,
inputPdf.GetPageSizeWithRotation(i).Height);
如果您对 inputPdf.GetPageRotation(i)
的调用返回 180,那么您可以在随后的 if
语句中处理此问题(使用我建议的轮换代码 == 180)。
【讨论】:
【参考方案5】:以上代码稍作改动 旧代码
case 270:
writer.DirectContent.AddTemplate(importedPage, 0, 1f, -1f, 0, pageWidth, 0);
新代码
case 270:
writer.DirectContent.AddTemplate(importedPage, 0, 1f, -1f, 0, pageHeight, 0);
这将解决 270 度旋转的问题
【讨论】:
上面的代码在 iTextSharp v 5.5 上完全没问题。以上是关于使用 iTextSharp 在 C# 中旋转 PDF的主要内容,如果未能解决你的问题,请参考以下文章