Rotate a single page 90 degrees with iTextSharp/VB in an existing multi-page PDF
I am trying to integrate iTextSharp into an existing Document Imaging application that allows users to rotate individual pages that may have been scanned in at an incorrect angle (it happens more often than I would have thought).
I have the actual page data rotating correctly across 90/180 degrees, but the page orientation is not rotating along with it. I have just started working with iTextSharp, so I'm still a little unfamiliar with its methods, but was able to cobble together what I have so far usin开发者_JAVA技巧g posts from StackOverflow. It's close, but not quite there.
Here's what I have so far:
' Get the input document and total number of pages
Dim inputPdf As New iTextSharp.text.pdf.PdfReader(fileName)
Dim pageCount As Integer = inputPdf.NumberOfPages
' Load the input document
Dim inputDoc As New iTextSharp.text.Document(inputPdf.GetPageSizeWithRotation(1))
' Set up the file stream for our output document
Dim outFileName As String = Path.ChangeExtension(fileName, "pdf")
Using fs As New FileStream(outFileName, FileMode.Create)
' Create the output writer
Dim outputWriter As iTextSharp.text.pdf.PdfWriter = iTextSharp.text.pdf.PdfWriter.GetInstance(inputDoc, fs)
inputDoc.Open()
' Copy pages from input to output document
Dim cb As iTextSharp.text.pdf.PdfContentByte = outputWriter.DirectContent
For index As Integer = 1 To pageCount
inputDoc.SetPageSize(inputPdf.GetPageSizeWithRotation(index))
inputDoc.NewPage()
' If this is our page to be rotated, perform the desired transform
' TODO - 90 degree rotations need to change the page orientation as well
Dim page As iTextSharp.text.pdf.PdfImportedPage = outputWriter.GetImportedPage(inputPdf, index)
If index = pageNum Then
Select Case angle
Case 90
cb.AddTemplate(page, 0, -1, 1, 0, 0, page.Height)
Case 180
cb.AddTemplate(page, -1, 0, 0, -1, page.Width, page.Height)
Case 270
cb.AddTemplate(page, 0, 1, -1, 0, page.Width, 0)
Case Else
' Should not be here, but don't do anything
cb.AddTemplate(page, 1, 0, 0, 1, 0, 0)
End Select
Else
' No rotation; add as is
cb.AddTemplate(page, 1, 0, 0, 1, 0, 0)
End If
Next
inputDoc.Close()
End Using
I tried adding the following code to the top to grab the page size from the existing page and swap the dimensions if the rotation angle was 90 or 270:
For index As Integer = 1 To pageCount
Dim pageSize As iTextSharp.text.Rectangle = inputPdf.GetPageSizeWithRotation(index)
If angle = 90 OrElse angle = 270 Then
' For 90-degree rotations, change the orientation of the page, too
pageSize = New iTextSharp.text.Rectangle(pageSize.Height, pageSize.Width)
End If
inputDoc.SetPageSize(pageSize)
inputDoc.NewPage()
Unfortunately, this had the effect of rotating every page 90 degrees, and the data on the page I wanted rotated didn't show up in the correct spot anyway (it was shifted down and off the page a bit).
Like I said, I'm not really familiar with the inner workings of the API. I have checked out the examples online at the sourceforge page, and have taken a look at the book (both editions), but I don't see anything that fits the bill. I saw an example here that shows page orientation for newly-composed PDFs, but nothing for existing ones. Can anybody help me out? Thanks!
You're making this harder than it needs to be.
Rather than rotating the page contents, you want to rotate the page itself:
PdfReader reader = new PdfReader(path);
PdfStamper stamper = new PdfStamper( reader, outStream );
PdfDictionary pageDict = reader.getPageN(desiredPage);
int desiredRot = 90; // 90 degrees clockwise from what it is now
PdfNumber rotation = pageDict.getAsNumber(PdfName.ROTATE);
if (rotation != null) {
desiredRot += rotation.intValue();
desiredRot %= 360; // must be 0, 90, 180, or 270
}
pageDict.put(PdfName.ROTATE, new PdfNumber(desiredRot);
stamper.close();
That's it. You can play around with desiredPage
and desiredRot
to get whatever effect you're after. Enjoy.
精彩评论