I'm trying to add a watermark in a pdf file in the center bottom of pdf file .. I tried many ways but i did not figure out how it's works exactly to select the location of watermark.
Anyway here is the code:
string filepath = #"~/Images/logo-01.png";
iTextSharp.text.Image pageIn = iTextSharp.text.Image.GetInstance(Server.MapPath(filepath));
pageIn.Alignment = iTextSharp.text.Image.ALIGN_MIDDLE;
pageIn.ScaleToFit(150, 150);
pageIn.Alignment = iTextSharp.text.Image.UNDERLYING;
pageIn.SetAbsolutePosition((PageSize.A4.Width - pageIn.ScaledWidth) / 2, (PageSize.A4.Height - pageIn.ScaledHeight) / 10);
Again i want to make the watermark position in the max center bottom of the page.
You may try using GroupDocs.Watermark for .NET that allows controlling the horizontal and vertical position of the watermark in the documents. This is how you can add watermark at the bottom of the pages in a PDF document:
using (PdfDocument doc = Document.Load<PdfDocument>("D:\\sample.pdf"))
{
// Add text watermark
TextWatermark watermark = new TextWatermark("Protected Document", new Font("Arial", 8));
watermark.HorizontalAlignment = HorizontalAlignment.Center;
watermark.VerticalAlignment = VerticalAlignment.Bottom;
doc.AddWatermark(watermark);
// Add image watermark
ImageWatermark imageWatermark = new ImageWatermark("D:\\watermark.png");
imageWatermark.HorizontalAlignment = HorizontalAlignment.Center;
imageWatermark.VerticalAlignment = VerticalAlignment.Bottom;
doc.AddWatermark(imageWatermark);
// Save document
doc.Save("D:\\output.pdf");
}
Disclosure: I work as a Developer Evangelist at GroupDocs.
Related
I am generating a pdf from others with IText7 in C# and I need to add information in a corner of each page automatically, I add the information but in some pages, the content occupies the entire page and I need the information to be left behind in those cases of the content, I attach the image of the result, thanks in advance
I am using a canvas and Div to add the text
PdfPage pag = pdfDocument.GetLastPage();
Canvas canvas = new Canvas(pag, pag.GetPageSize());
var div = new Div().SetMargin(0).SetPadding(0).SetKeepTogether(true);
div.SetFixedPosition(0, 0, pag.GetPageSize().GetWidth());
div.Add(new Paragraph("info").SetFontSize(12));
canvas.Add(div);
canvas.Close();
Sorry my English
result:
Pdf text added result
expected:
Pdf text added Expected
I have found the solution, I create a PDFCanvas and indicate that NewContentStreamBefore(), and it already adds the information behind the page
PdfPage pag = pdfDocument.GetLastPage();
PdfCanvas under = new PdfCanvas(pag.NewContentStreamBefore(), pag.GetResources(), pdfDocument);
Canvas canvas = new Canvas(under, pag.GetPageSize());
var div = new Div().SetMargin(0).SetPadding(0).SetKeepTogether(true);
div.SetFixedPosition(0, 0, pag.GetPageSize().GetWidth());
div.Add(new Paragraph("info").SetFontSize(12));
canvas.Add(div);
canvas.Close();
I have some code used to watermark PDFs using iTextSharp. The code works fine for most PDFs, but there has been one test case where the watermark is not visible on a PDF of a scanned document. (I have other scanned documents where it does appear though).
I am using the GetOverContent() method.
This is my code for adding the watermark;
using (PdfReader reader = new PdfReader(this.inputFilename))
{
// Set transparent - 1
PdfGState gstate = new PdfGState();
gstate.FillOpacity = 0.4f;
gstate.StrokeOpacity = 0.5f;
// 2
BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, Encoding.ASCII.EncodingName, false);
using (var stream = new MemoryStream())
{
var pdfStamper = new PdfStamper(reader, stream);
// Must start at 1 because 0 is not an actual page.
for (int i = 1; i <= reader.NumberOfPages; i++)
{
Rectangle pageSize = reader.GetPageSizeWithRotation(i);
// Gets the content ABOVE the PDF, Another option is GetUnderContent(...)
// which will place the text below the PDF content.
PdfContentByte pdfPageContents = pdfStamper.GetOverContent(i);
pdfPageContents.BeginText(); // Start working with text.
// 1
pdfPageContents.SaveState();
pdfPageContents.SetGState(gstate);
float hypotenuse = (float)Math.Sqrt(Math.Pow(pageSize.Width, 2) + Math.Pow(pageSize.Height, 2));
float glyphWidth = baseFont.GetWidth("My watermark text");
float fontSize = 1000 * (hypotenuse * 0.8f) / glyphWidth;
float angle = (float)(Math.Atan(pageSize.Height / pageSize.Width) * (180 / Math.PI));
// Create a font to work with
pdfPageContents.SetFontAndSize(baseFont, fontSize);
pdfPageContents.SetRGBColorFill(128, 128, 128); // Sets the color of the font, GRAY in this instance
// Note: The x,y of the Pdf Matrix is from bottom left corner.
// This command tells iTextSharp to write the text at a certain location with a certain angle.
// Again, this will angle the text from bottom left corner to top right corner and it will
// place the text in the middle of the page.
pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "My watermark text", pageSize.Width / 2, pageSize.Height / 2, angle);
pdfPageContents.EndText(); // Done working with text
pdfPageContents.RestoreState();
}
pdfStamper.FormFlattening = true; // enable this if you want the PDF flattened.
pdfStamper.FreeTextFlattening = true; // enable this if you want the PDF flattened.
pdfStamper.Close(); // Always close the stamper or you'll have a 0 byte stream.
return stream.ToArray();
}
}
Does anyone have any ideas as to why the watermark may not be appearing and what I can try to fix it?
Kind regards.
The code is based on an assumption it even documents as a fact:
// Note: The x,y of the Pdf Matrix is from bottom left corner.
// This command tells iTextSharp to write the text at a certain location with a certain angle.
// Again, this will angle the text from bottom left corner to top right corner and it will
// place the text in the middle of the page.
pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "My watermark text", pageSize.Width / 2, pageSize.Height / 2, angle);
The assumption that the x,y of the Pdf Matrix is from bottom left corner unfortunately is wrong: While it indeed is very often the case that the origin of the PDF coordinate system (the default user space coordinate system, to be more precise) is in the lower left corner of the page, this is not required, the origin actually can be literally anywhere (within reasonable limits).
Thus, one has to take the lower left coordinates of the Rectangle pageSize into consideration, too.
The OP meanwhile has confirmed:
I had assumed that the bottom left of the page would have co-ordinates of (0,0) but for this document the co-ordinates were (0, 7022).
public void RenderCanvasImage(int maxRight, int maxBottom, Canvas surface, Transform transform)
{
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(maxRight, maxBottom, 96d, 96d, PixelFormats.Pbgra32);
renderBitmap.Render(surface);
PrintDialog dialog = new PrintDialog();
if (dialog.ShowDialog() != true)
{
return;
}
Grid grid = new Grid();
Image myImage = new Image();
myImage.Source = renderBitmap;
myImage.Stretch = Stretch.Uniform;
grid.Children.Add(myImage);
Grid.SetColumn(myImage, 0);
Grid.SetRow(myImage, 1);
grid.Measure(new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight));
grid.Arrange(new Rect(new Point(0, 0), grid.DesiredSize));
dialog.PrintVisual(grid, "My Canvas");
surface.LayoutTransform = transform;
}
I am using above code to print my canvas with Microsoft Print to PDF. Its working fine in all cases but when i enter comma in file name e.g.(Print,Test) while printing. It doesn't save my file and also not providing any error/exception code by which i could intimate the user to change file name.
Please help me to resolve my problem.
In short, don't do it
This is a known bug when printing to PDF
Use a different driver or don't put a comma in the file name
Its not only from WPF, its in general in certain situations.
Bug in "Print to PDF" and "Print to XPS" in Windows 10? comma in filename results in zero-byte file
Microsoft Print to PDF not working
Found a bug in Microsoft Print to PDF
Microsoft Print to PDF in Windows 10
I need to have a table with multiple columns where I have different coloured circles in different cells with a number in the middle of the circle.
Similar to the mockup below but with everything centralized and equal.
I have tried the following:
PdfContentByte canvas = writer.DirectContent;
PdfTemplate template = canvas.CreateTemplate(40, 40);
template.SetLineWidth(1f);
template.Circle(15f, 15f, 15);
template.Stroke();
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(template);
img.Alignment = iTextSharp.text.Image.UNDERLYING | iTextSharp.text.Image.ALIGN_CENTER;
Phrase imgPhrase = new Paragraph(new Chunk(img, 1f, 1f));
PdfPCell meAnswerCell = new PdfPCell();
meAnswerCell.Colspan = 1;
meAnswerCell.BorderWidthBottom = 0;
meAnswerCell.HorizontalAlignment = Element.ALIGN_CENTER;
string meAnswerText = "1;
Phrase phrase = new Phrase(meAnswerText, questionFont);
Paragraph para = new Paragraph();
para.Add(imgPhrase);
para.Add(phrase);
para.Alignment = Element.ALIGN_CENTER;
meAnswerCell.AddElement(para);
answersTable.AddCell(meAnswerCell);
but I end up with something like this. (I haven't tried setting the colour yet). I cannot get the image and the text to sit in the same place.
I have also tried following this post:
iTextSharp - Text overlapping image
which explains how to put an event on the cell to set the background image of the cell but my circle appears half way down the page.
Has anyone go an example of this working?
There are many different ways to achieve what you want.
Actually, I just voted to close a question https://stackoverflow.com/questions/28066639/how-to-get-text-on-image-in-itext-using-java because it was a duplicate of How to add text to an image?
In your case, you may also benefit from the documentation. There are some examples in The Best iText Questions on StackOverflow that explain how to use cell events, but your requirement is very similar to what was done in a couple of examples from the book iText in Action - Second Edition.
You could use cell events to draw the background of a cell, as shown in the Calendar examples: calendar.pdf, but your requirement can also be met using a generic tag event: movie_years.pdf
Do you see how the word IMDB nicely fits inside an ellipse? You could fit a number inside a circle in the exact same way.
With this code, one draws an ellipse (changing it into a circle is fairly easy):
class GenericTags : PdfPageEventHelper {
public override void OnGenericTag(
PdfWriter writer, Document pdfDocument, Rectangle rect, String text) {
PdfContentByte content = writer.DirectContentUnder, rect);
content.SaveState();
content.SetRGBColorFill(0x00, 0x00, 0xFF);
content.Ellipse(
rect.Left - 3f, rect.Bottom - 5f,
rect.Right + 3f, rect.Top + 3f
);
content.Fill();
content.RestoreState();
}
}
With this snippet, you introduce this event:
GenericTags gevent = new GenericTags();
writer.PageEvent = gevent;
With this snippet, you mark a Chunk with the generic tag:
chunk.SetGenericTag("circle");
I have a problem with regards on the page orientation of the paper size.
I have a pdf file which contains portrait and landscape page.
this code works perfectly.
string FileLocation = "c:\\Temp\\SomeFile.pdf";
string WatermarkLocation = "c:\\Temp\\watermark.gif";
Document document = new Document();
PdfReader pdfReader = new PdfReader(FileLocation);
PdfStamper stamp = new PdfStamper(pdfReader, new FileStream(FileLocation.Replace(".pdf","[temp][file].pdf"), FileMode.Create));
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(WatermarkLocation);
img.SetAbsolutePosition(250,300); // set the position in the document where you want the watermark to appear (0,0 = bottom left corner of the page)
PdfContentByte waterMark;
for (int page = 1; page <= pdfReader.NumberOfPages; page++)
{
waterMark = stamp.GetUnderContent(page);
waterMark.AddImage(img);
}
stamp.FormFlattening = true;
stamp.Close();
// now delete the original file and rename the temp file to the original file
File.Delete(FileLocation);
File.Move(FileLocation.Replace(".pdf", "[temp][file].pdf"), FileLocation);
since I'm using absolute value to set the image position.
img.SetAbsolutePosition(250,300);
How can T set the image position if the page is landscape or portrait?
note: One pdf with landscape and portrait page orientation.
Is there by chance that I can use if statement?
if (//paper is landscape)
{
//code here
}
else
{
//code here
}
What do you want to achieve?
Normally, iText takes into account the value of the page rotation. This means that when a page is rotated, the coordinates will be rotated too.
If you want to overrule this, you can add this line:
stamper.RotateContents = false;
This is explained in Chapter 6 of my book. You can try this example to see the difference:
No rotation, text added normally: hello1.pdf
Rotation, text added normally ( = rotated): hello2.pdf
Rotation, text added with rotation ignored: hello3.pdf
Of course, this assumes that a rotation was defined for the pages. Sometimes, landscape is mimicked by defining a different page size instead of defining a rotation.
In that case, you should also read Chapter 6 because it explains how to get the MediaBox of a document. see the example PageInformation that introduces methods such as GetPageSize(), GetRotation() and GetPageSizeWithRotation().
This is all documented, but if it doesn't answer your question, please clarify. As demonstrated in the example, the rotation is taken into account by default when adding new content, so maybe I misunderstood the question.