iText - How to rotate pdf content without rotating a page

Viewed 645

I have pdf file in which are lot of post labels pages that have Portrait orientation. I need to shrink the existing content of every page and then add additional information into every page. For this reason I use PDFStamper class which in the code below successfully shrinks the content. Then the next requirement is to rotate content of the page 90 or 270 degrees without rotating the page. Page must leave in Portrait orientation, but the shrunk content must be rotated. I tried to use PdfDictionary class and tested a lot of code variations but the content wasn't rotated as required. I need proposals what code block must be after comment in code - //Code to rotate only content of pdf page 90 or 270 degrees leaving page in Portrait orientation??? My code is below:

using iTextSharp.text.pdf;
using Microsoft.Win32;
using System;
using System.IO;

namespace RotatePDFContent
{
    internal class Program
    {
        [STAThread]
        private static void Main(string[] args)
        {
            string directory = AppDomain.CurrentDomain.BaseDirectory;
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = directory;
            ofd.DefaultExt = ".pdf";
            ofd.Filter = "PDF Files(.*PDF)|*.PDF|All Files(*.*)|*.*";
            string inputPdfFilePath;
            if (ofd.ShowDialog() == true)
            {
                inputPdfFilePath = ofd.FileName.ToString();
                using (Stream inputPdfStream = new FileStream(inputPdfFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {

                    PdfReader pdfReader = new PdfReader(inputPdfStream);
                    int pagesAmount = pdfReader.NumberOfPages;

                    string pdfInputsDirectoryPath = System.IO.Path.GetDirectoryName(inputPdfFilePath);

                    string resultFileName = "Output_" + Path.GetFileNameWithoutExtension(inputPdfFilePath) +
                        Path.GetExtension(inputPdfFilePath);
                    string resultFilePath = System.IO.Path.Combine(pdfInputsDirectoryPath, resultFileName);
                    using (Stream outputPdfStream =
                        new FileStream(resultFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        PdfStamper stamper = new PdfStamper(pdfReader, outputPdfStream);

                        for (int pageNumber = 1; pageNumber <= pagesAmount; pageNumber++)
                        {
                            //Shrink original page contents for the purpose to fit into required area
                            stamper.GetUnderContent(pageNumber).SetLiteral("\nq 0.53 0 0 0.53 10 25 cm\nq\n");

                            //Code to rotate only content of pdf page 90 or 270 degrees leaving page 
                           //in Portrait orientation???
                          //????????????  
                        }
                        stamper.Close();
                    }
                }
            }
        }
    }
}

I look at the question iText - Rotate page content while creating PDF, but didn't find solution to my code from this question until now. In the attached images are initial and required result. Initial Required result

1 Answers

In the code below is my solution. In this solution is used temporary file in which is saved shrunk and rotated to Landscape orientation pdf page content. After the first step code opens temporary file, rotates pdf content to Portrait orientation (which is the required content position) and save the result to file.

using iTextSharp.text.pdf;
using Microsoft.Win32;
using System;
using System.IO;

namespace RotatePDFContent
{
    internal class Program
    {
        [STAThread]
        private static void Main(string[] args)
        {
            string directory = AppDomain.CurrentDomain.BaseDirectory;
            
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = directory;
            ofd.DefaultExt = ".pdf";
            ofd.Filter = "PDF Files(.*PDF)|*.PDF|All Files(*.*)|*.*";
            string inputPdfFilePath;
            if (ofd.ShowDialog() == true)
            {
                inputPdfFilePath = ofd.FileName.ToString();
                string temporaryFilePath = string.Empty;
                string pdfInputsDirectoryPath = System.IO.Path.GetDirectoryName(inputPdfFilePath);

                using (Stream inputPdfStream = new FileStream(inputPdfFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    PdfReader pdfReader = new PdfReader(inputPdfStream);


                    #region Create temporary file to rotate page without content rotation and shrink content
                    //this part of code is created because without saving rotated to Landscape orientatio pdf file and reading it again
                    //into pdf stream didn't find other solution which set content in Portrait orienation page into required horizontal
                    //position

                    string temporaryFileName = "Temporary_" + Path.GetFileNameWithoutExtension(inputPdfFilePath) +
                                Path.GetExtension(inputPdfFilePath);
                    temporaryFilePath = System.IO.Path.Combine(pdfInputsDirectoryPath, temporaryFileName);
                    using (Stream outputPdfStream =
                        new FileStream(temporaryFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        PdfStamper stamper = new PdfStamper(pdfReader, outputPdfStream);

                        int pagesAmount = pdfReader.NumberOfPages;

                        for (int pageNumber = 1; pageNumber <= pagesAmount; pageNumber++)
                        {
                            //This code rotates all page 
                            PdfDictionary page = pdfReader.GetPageN(pageNumber);
                            PdfNumber rotate = page.GetAsNumber(PdfName.ROTATE);

                            int rotation = rotate == null ? 270 : (rotate.IntValue + 270) % 360;
                            stamper.RotateContents = true;//this line leave content of page not rotated
                            page.Put(PdfName.ROTATE, new PdfNumber(rotation));
                            stamper.GetUnderContent(pageNumber).SetLiteral("\nq 0.53 0 0 0.53 10 25 cm\nq\n");
                            
                        }
                        stamper.Close();
                    }

                    #endregion Create temporary file to rotate page without content rotation and shrink content
                }

                #region Create new  pdfReader and load into it data from temporary file and then rotate pages to required position

                using (Stream inputPdfStream = new FileStream(temporaryFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    PdfReader pdfReader = new PdfReader(inputPdfStream);
                    File.Delete(temporaryFilePath);
                    string resultFileName = "Output_" + Path.GetFileNameWithoutExtension(inputPdfFilePath) +
                        Path.GetExtension(inputPdfFilePath);
                    string resultFilePath = System.IO.Path.Combine(pdfInputsDirectoryPath, resultFileName);
                    using (Stream outputPdfStream =
                        new FileStream(resultFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        PdfStamper stamper = new PdfStamper(pdfReader, outputPdfStream);
                        int pagesAmount = pdfReader.NumberOfPages;

                        for (int pageNumber = 1; pageNumber <= pagesAmount; pageNumber++)
                        {
                            //This code rotates all page 
                            PdfDictionary page = pdfReader.GetPageN(pageNumber);
                            PdfNumber rotate = page.GetAsNumber(PdfName.ROTATE);
                            stamper.RotateContents = true;//this line leave content of page not rotated

                            int rotation = rotate == null ? 90 : (rotate.IntValue + 90) % 360;
                            page.Put(PdfName.ROTATE, new PdfNumber(rotation));
                            //after the above code line execution the initial content of pdf document is in the correct position 

                        }
                        stamper.Close();
                    }
                }

                #endregion Create new  pdfReader and load into it data from temporary file and then rotate pages to required position

            }
        }
    }
}
Related