Resize pdf page, set margins ans the right rotation - c#

Im working on a project where i have to resize a pdf file as input ( from A3 to A4 ), respecting the right rotation of the original document and at end add Margins all around the content.
Im using actually iTextSharp to do this, but my problem that i manage to do the resize and rotation part, but NO OK for the margins (code bellow). The SetMargins() don't change any marging !
Please anyone ca me solve this problem ?
Thanks in advance
/// Start resizing
/// using iTextsharp lib
/// Read the input file
iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(filePath);
/// GĂ©nerate the new file
Document doc = new Document() ;
/// Check input PDF rotation
iTextSharp.text.Rectangle rectangle = reader.GetPageSizeWithRotation(1);
if (rectangle.Height < rectangle.Width)
{
label7.Text = "Paysage";
rotation = 90;
}
else
{
label7.Text = "Portrait";
rotation = 0;
}
/// Create new A4 pdf with the correct rotation
if (rotation == 0)
{
doc = new Document(PageSize.A4);
doc.SetMargins(50, 50, 50, 50);
float marg = doc.BottomMargin;
}
else if (rotation == 90)
{
doc = new Document(PageSize.A4.Rotate());
doc.SetMargins(50, 50, 50, 50);
float marg = doc.BottomMargin;
}
/// Start generating the new PDF
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc,new FileStream("Testing folder/" + fileNameWithoutExtention+"_mod.PDF",FileMode.Create));
/// Open the new PDF and manage content
doc.Open();
for (int i = 1; i <= pagesNbr; i++)
{
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page = writer.GetImportedPage(reader, i);
float Scale = 0.67f;
doc.NewPage();
cb.AddTemplate(page, Scale, 0, 0, Scale, 0, 0);
}
this code generate a new PDF with the right size A4, right orientation, but the content is on the left-bottom side of the page ! i need it to be in the center of the page and i can manage the margins !

Related

iText 7 watermark canvas not appearing correctly in some special 3d pdf

I have been using iText7 latest .net package to create watermark annotation on pdf document. I see for most of the noraml pdf files watermark is stamped properly in the desired position however for some special 3d(dimensional) pdf files the watermark is strangely not appearning properly, what I believe that some part of the watermark is gettting cut by the other 3d layers. Here is the screenshot of distortion experienced. I am trying to understand and solve this problem but unable to get any clue. Can someone help? Here is the sample pdf in case you want to take a look.
Here is the very short relevant code which I am using to embed watermark.
float watermarkTrimmingRectangleWidth = 500;
float watermarkTrimmingRectangleHeight = 500;
float formWidth = 500;
float formHeight = 500;
float formXOffset = -40;
float formYOffset = 0;
float xTranslation = 50;
float yTranslation = 25;
double rotationInRads = Math.PI / 4.2;
PdfDocument pdfDoc = new PdfDocument(new PdfReader(filePath), new PdfWriter(destinationfile));
var numberOfPages = pdfDoc.GetNumberOfPages();
PdfPage page = null;
for (var i = 1; i <= numberOfPages; i++)
{
page = pdfDoc.GetPage(i);
Rectangle ps = page.GetPageSize();
float bottomLeftX = ps.GetWidth() / 2 - watermarkTrimmingRectangleWidth / 2;
float bottomLeftY = ps.GetHeight() / 2 - watermarkTrimmingRectangleHeight / 2;
Rectangle watermarkTrimmingRectangle = new Rectangle(bottomLeftX, bottomLeftY, ps.GetWidth(), watermarkTrimmingRectangleHeight);
PdfWatermarkAnnotation watermark = new PdfWatermarkAnnotation(watermarkTrimmingRectangle);
AffineTransform transform = new AffineTransform();
transform.Translate(xTranslation, yTranslation);
transform.Rotate(rotationInRads);
PdfFixedPrint fixedPrint = new PdfFixedPrint();
watermark.SetFixedPrint(fixedPrint);
Rectangle formRectangle = new Rectangle(formXOffset, formYOffset, formWidth, formHeight);
//Observation: font XObject will be resized to fit inside the watermark rectangle
PdfFormXObject form = new PdfFormXObject(formRectangle);
PdfExtGState gs1 = new PdfExtGState().SetFillOpacity(0.8f).SetStrokeOpacity(1.5f);
PdfCanvas canvas = new PdfCanvas(form, pdfDoc);
float[] transformValues = new float[6];
transform.GetMatrix(transformValues);
canvas.SaveState()
.BeginText().SetExtGState(gs1)
.SetTextMatrix(transformValues[0], transformValues[1], transformValues[2], transformValues[3], transformValues[4], transformValues[5])
.SetFontAndSize(font, fontSize)
.ShowText("Restricted Internal")
.EndText()
.RestoreState();
canvas.Release();
watermark.SetAppearance(PdfName.N, new PdfAnnotationAppearance(form.GetPdfObject()));
watermark.SetFlags(PdfAnnotation.READ_ONLY);
page.AddAnnotation(watermark);
}
page?.Flush();
pdfDoc.Close();
Your watermark annotation is drawn on top of some form fields.
Because the display order for page elements is page content, annotations, form fields, your annotation appearance is blocked by the form fields.

Adding text as watermark using itext7 C#

I am using the below code to add watermark to my pdf.
private void Merge(List<string> src, string dest)
{
iTextKernel.PdfWriter writer = new iTextKernel.PdfWriter(dest);
iTextKernel.PdfDocument pdfDocument1 = new iTextKernel.PdfDocument(new iTextKernel.PdfReader(src[0]), writer);
pdfDocument1.AddEventHandler(PdfDocumentEvent.END_PAGE, new WatermarkingEventHandler());
for (int i = 1, max = src.Count; i < max; i++)
{
iTextKernel.PdfDocument pdfDocument2 = new iTextKernel.PdfDocument(new iTextKernel.PdfReader(src[i]));
var pagesCount = pdfDocument2.GetNumberOfPages();
pdfDocument2.CopyPagesTo(1, pagesCount, pdfDocument1);
pdfDocument2.Close();
}
pdfDocument1.Close();
protected class WatermarkingEventHandler : IEventHandler {
public void HandleEvent(Event e) {
PdfDocumentEvent docEvent = (PdfDocumentEvent) e;
iTextKernel.PdfDocument pdfDoc = docEvent.GetDocument();
iTextKernel.PdfPage page = docEvent.GetPage();
iText.Kernel.Font.PdfFont font = null;
try {
font = PdfFontFactory.CreateFont(FontConstants.HELVETICA_BOLD);
} catch (IOException ex) {
//_log.Error(ex);
}
PdfCanvas canvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc);
new Canvas(canvas, pdfDoc, page.GetPageSize())
.SetFontColor(iText.Kernel.Colors.DeviceGray.LIGHT_GRAY)
.SetFontSize(60)
.SetFont(font)
.ShowTextAligned(new Paragraph("FOR YOUR RECORDS ONLY: DO NOT SUBMIT"), 298, 421, pdfDoc.GetPageNumber(page),
TextAlignment.CENTER, VerticalAlignment.MIDDLE, 45);
}
But am getting the watermark only in the last page that too hidden under the contents. Could you please modify this code so that i could get the watermark on all the pages and shown over the contents.
Please take a look at the iText 7 for C# jump-start tutorial, more specifically Chapter 5: Manipulating an existing PDF document. Scroll to the part where it says: "Adding a header, footer, and watermark" and look at the example:
PdfDocument pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
Document document = new Document(pdfDoc);
Rectangle pageSize;
PdfCanvas canvas;
int n = pdfDoc.GetNumberOfPages();
for (int i = 1; i <= n; i++) {
PdfPage page = pdfDoc.GetPage(i);
pageSize = page.GetPageSize();
canvas = new PdfCanvas(page);
//Draw header text
}
pdfDoc.close();
As you can see, we only need one PdfDocument instance, but instead of passing only a PdfWriter, we also pass a PdfReader instance. We will read the file with path src and we will write to a file with path dest.
You want to add content to each page. This means that you have to loop over each page (from 1 to n). Get the PdfPage object for each page i and replace the line //Draw header text with whatever it is you want to do.
In your case, you add an image underneath the existing content. That is the normal thing to do, but you say that the watermark is covered by the existing content. That happens for instance when the actual content consists of images (e.g. scanned pages). If you add a watermark under the pages of a PDF that consists of scanned pages, you will never see the watermark.
In that case, you have to add the content on top of the existing content, but it is best to make the watermark transparent:
Paragraph p = new Paragraph("FOR YOUR RECORDS ONLY: DO NOT SUBMIT").SetFontSize(60);
canvas.SaveState();
PdfExtGState gs1 = new PdfExtGState().SetFillOpacity(0.2f);
canvas.SetExtGState(gs1);
document.ShowTextAligned(p, pageSize.GetWidth() / 2, pageSize.GetHeight() / 2, pdfDoc.GetPageNumber(page), TextAlignment.CENTER, VerticalAlignment.MIDDLE, 45);
canvas.RestoreState();
Note that in the tutorial, we are using pageSize.GetWidth() / 2 and pageSize.GetHeight() / 2 as coordinates, which means that we assume that the lower-left corner of the page has the coordinate (0, 0). That may not be the case. You may have to add the x-offset and the y-offset to that value.

Blank PDF generate when WriteCompatiblePdf method call of ITextSharp

Hi i am using below code. When i upload some of PDF's which contain some content and after uploading, their is no content on uploaded PDF. Uploaded PDf is blank. I am using below method of ItextSharp for change the version of Orginial PDF to Defined Version.
private int WriteCompatiblePdf(string fileName, FileUpload filePath)
{
string sNewPdf = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["InterfaxPath"]) + fileName;
iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(filePath.FileBytes);
// we retrieve the total number of pages
int n = reader.NumberOfPages;
// step 1: creation of a document-object
iTextSharp.text.Document document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
// step 2: we create a writer that listens to the document
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, new FileStream(sNewPdf, FileMode.Create, FileAccess.ReadWrite));
//write pdf that pdfsharp can understand
writer.SetPdfVersion(iTextSharp.text.pdf.PdfWriter.PDF_VERSION_1_4);
// step 3: we open the document
document.Open();
iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
iTextSharp.text.pdf.PdfImportedPage page;
int rotation;
int i = 0;
while (i < n)
{
i++;
document.SetPageSize(reader.GetPageSizeWithRotation(i));
document.NewPage();
page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
// step 5: we close the document
document.Close();
return n;
}
Any recommendations?
The OP provided a sample "blank" file.
As it turns out, this "blank" file does contain the desired content, it merely is way off-page.
Details
The pages of the document have this media box definition:
/MediaBox[0 7072 612 7864]
Thus, the visible area has x coordinates in 0..612 and y coordinates in 7072..7864. When adding the imported page contents, though, the OP explicitly anchors them explicitly at the coordinates 0,0:
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
The contents of the former page, therefore, are added in the area with y coordinates 0..792. So, they are not visible.
Resolutions
There are different ways to resolve this issue:
add the contents at the position with the correct coordinates, i.e. use
cb.AddTemplate(page, 1f, 0, 0, 1f, x, y);
where x and y are Left and Bottom of reader.GetPageSizeWithRotation(1) (a Rectangle); or
normalize the page size rectangle for the Document constructor to be based in 0,0; or
use a PdfStamper with the PdfReader instead of the PdfWriter and use it to select the desired version.
it's because you're not set any text to be written in the PDF. this is a simple example how to write text
string newFile = #"C:\the path\file.pdf";
Document doc = new Document(iTextSharp.text.PageSize.A4, 10, 10, 42, 35);
PdfWriter write = PdfWriter.GetInstance(doc, new FileStream(newFile,
FileMode.Create));
doc.Open(); // open the connection
Paragraph p1 = new Paragraph("text to be displayed in the first paragraph");
doc.Add(p1); // close the connection
this link will tell you the proper way to write from iTextSharp more advanced

Main content is overlapping on footer section PDF document iTextSharp

i am using itextsharp for creating document. I have created a footer section in document but content that over the top of footer is overlapping.
How can i fix this?
I want to add page number on each page how can i do this?
Please check this link
Pdf document Image
public class PdfNote
{
public int Create(int id, string path)
{
try
{
var file = path;
if (System.IO.File.Exists(file))
System.IO.File.Delete(file);
Document document = new Document(PageSize.A4, 10, 10, 10, 10);
var writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, new System.IO.FileStream(file, FileMode.Create));
document.Open();
writer.PageEvent = new Footer();
// main content
document.Close();
return 1;
}
catch (Exception ex)
{
throw ex;
}
}
public partial class Footer : PdfPageEventHelper
{
public override void OnEndPage(PdfWriter writer, Document doc)
{
PdfPTable fTbl = new PdfPTable(1);
fTbl.TotalWidth = 550;
fTbl.DefaultCell.Border = 0;
PdfPTable line = new PdfPTable(1);
line.DefaultCell.Border = 0;
line.DefaultCell.BorderWidthBottom = 0.2f;
line.DefaultCell.Padding = 5;
line.AddCell("");
fTbl.AddCell(line);
PdfPTable footerTbl = new PdfPTable(3);
footerTbl.TotalWidth = 550;
footerTbl.DefaultCell.Column.Alignment = 1;
footerTbl.HorizontalAlignment = Element.ALIGN_CENTER;
footerTbl.DefaultCell.Border = 0;
footerTbl.AddCell("Print Name:");
footerTbl.AddCell("Signature:");
footerTbl.AddCell("Date:");
PdfPCell cell = new PdfPCell();
cell.Padding = 20;
cell.Border = 0;
cell.BorderWidthBottom = 1;
footerTbl.AddCell(cell);
footerTbl.AddCell(cell);
footerTbl.AddCell(cell);
fTbl.AddCell(footerTbl);
fTbl.AddCell(line);
fTbl.WriteSelectedRows(0, -1, 15, 110, writer.DirectContent);
}
}
}
In a nutshell:
In
Document document = new Document(PageSize.A4, 10, 10, 10, 10);
you tell iText to hardly leave any margin (e.g. for use for footer lines) at all. Thus, it is not surprising that your footer
fTbl.WriteSelectedRows(0, -1, 15, 110, writer.DirectContent);
every so often overlaps the content.
So simply adjust the margins (especially the bottom one) and the footer position to not overlap each other.
In more detail:
The Document constructor you use is documented as
/// <summary>
/// Constructs a new Document-object.
/// </summary>
/// <param name="pageSize">the pageSize</param>
/// <param name="marginLeft">the margin on the left</param>
/// <param name="marginRight">the margin on the right</param>
/// <param name="marginTop">the margin on the top</param>
/// <param name="marginBottom">the margin on the bottom</param>
public Document(Rectangle pageSize, float marginLeft, float marginRight, float marginTop, float marginBottom) {
Thus your new Document(PageSize.A4, 10, 10, 10, 10) instructs iText to create a document in A4 size and to merely leave 10 points free margin space in every direction when filling it with content. 10 points ain't much.
The table writing method of PdfPTable you use is documented as
/**
* Writes the selected rows to the document.
*
* #param rowStart the first row to be written, zero index
* #param rowEnd the last row to be written + 1. If it is -1 all the
* rows to the end are written
* #param xPos the x write coordinate
* #param yPos the y write coordinate
* #param canvas the <CODE>PdfContentByte</CODE> where the rows will
* be written to
* #return the y coordinate position of the bottom of the last row
*/
public float WriteSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas)
Thus, your code
fTbl.WriteSelectedRows(0, -1, 15, 110, writer.DirectContent);
starts drawing the table at the coordinate (15, 110) --- the origin (0, 0) here is the bottom left corner of your document.
Thus, obviously, page content area and footer area overlap in the stripe 10 <= y <= 110. You should increase the bottom margin (the last parameter in your Document constructor) and decrease the y position of the table drawing call to not overlap anymore.

Rotate PDF page contents and not the actual page

I have researched this and tried to rotate a single page PDF's contents. I am able to rotate the page 90, 180 or 270 degrees. I don't want to rotate the page but rather the contents.
Here's the method I have adapted so far:
public static byte[] RotatePdf(byte[] fileBytes, int degreesClockwise)
{
if (degreesClockwise % 90 != 0)
throw new ApplicationException(string.Format("degreesClockwise must be 0, 90, 180, 360: {0}", degreesClockwise));
PdfReader reader = new PdfReader(fileBytes);
using (var fs = new MemoryStream())
{
PdfStamper stamper = new PdfStamper(reader, fs);
PdfDictionary pageDict = reader.GetPageN(1);
int desiredRotation = degreesClockwise; // x degrees clockwise from what it is now
PdfNumber rotation = pageDict.GetAsNumber(PdfName.ROTATE);
if (rotation != null)
{
desiredRotation += rotation.IntValue;
desiredRotation %= 360; // must be 0, 90, 180, or 270
}
pageDict.Put(PdfName.ROTATE, new PdfNumber(desiredRotation));
stamper.Close();
return fs.ToArray();
}
}
Any suggestions would be greatly appreciated.
I accomplished the code using the PdfSharp library as I could not find any examples or answers for iTextSharp unfortunately.
Here is the code I used to accomplish what I wanted:
// Create the output document
PdfDocument outputDocument = new PdfDocument();
// Show single pages
// (Note: one page contains two pages from the source document)
outputDocument.PageLayout = PdfPageLayout.SinglePage;
// Open the external document as XPdfForm object
XPdfForm form = XPdfForm.FromFile(filename);
for (int i = 0; i < form.PageCount; i++)
{
// Add a new page to the output document
PdfPage page = outputDocument.AddPage();
page.Orientation = PageOrientation.Landscape;
double width = page.Width;
double height = page.Height;
int rotate = page.Elements.GetInteger("/Rotate");
XGraphics gfx = XGraphics.FromPdfPage(page);
XRect box = new XRect(0, 0, width, height * 2);
// Draw the page identified by the page number like an image
gfx.DrawImage(form, box);
}
// Save the document...
filename = "RotatedAndStretched_tempfile.pdf";
outputDocument.Save(filename);

Categories

Resources