A watermark image and table in itext - Edited - itext

I want to insert a table over a watermark image. I have followed many steps but all help in writing over the image not inserting a table.
Edit:
the image should be inserted in each page in the pdf document. i want to write over it using pdfdTable. all searches describe how to write a text over a watermark.
e.g:
document.add(getWatermarkedImage(cb, img, "some text"));
if i added the pdfdtable to the document as document.add(table); it wont be over the image. it will inserted above the image.
as this is my table:
outerCell = new PdfPCell(new Paragraph(" header 1"));
outerCell.setColspan(70);
outerCell.setBackgroundColor(BaseColor.LIGHT_GRAY);
outerTable.addCell(outerCell);
how could i insert this outertable above the watermark

Your question sounds wrong. It's as if you want to add an image watermark to a document, which is adequately explained in many other questions such as Set a fix background image for all my pages in PDF iText ASP C# and How can I add an image to all pages of my PDF? (These answers are about C# questions, but the official web site has many watermark and page event examples.)
Just like madhesh, you confuse the StackOverflow readers, even after you've read my answer to the question How to add text to an image? where I wrote:
This is a good example of a question that is phrased in a way that nobody can answer it correctly. After a lot of back and forth comments, it was finally clear that the OP wanted to add a text watermark to an image. Badly phrase questions can be very frustrating. Please take that in consideration when asking a question. In this case, I gave several wrong answers before it became clear what was actually asked.
You want to add a PdfPTable to an Image and your knowledge is insufficient to understand and adapt the examples provided with the answers to questions such as How to add text to an image? and Draw Lines on Image in PDF using ItextSharp.
What you're asking is extremely simple though.
The getWatermarkedImage() method that you mention looks like this:
public Image getWatermarkedImage(PdfContentByte cb, Image img) throws DocumentException {
float width = img.getScaledWidth();
float height = img.getScaledHeight();
PdfTemplate template = cb.createTemplate(width, height);
template.addImage(img, width, 0, 0, height, 0, 0);
template.saveState();
template.setColorStroke(BaseColor.GREEN);
template.setLineWidth(3);
template.moveTo(width * .25f, height * .25f);
template.lineTo(width * .75f, height * .75f);
template.moveTo(width * .25f, height * .75f);
template.lineTo(width * .25f, height * .25f);
template.stroke();
template.setColorStroke(BaseColor.WHITE);
template.ellipse(0, 0, width, height);
template.stroke();
template.restoreState();
return Image.getInstance(template);
}
This is the example taken from the answer to the question How to draw lines on an image?
You don't want to draw lines, so you can remove all the code that draws lines:
public Image getWatermarkedImage(PdfContentByte cb, Image img) throws DocumentException {
float width = img.getScaledWidth();
float height = img.getScaledHeight();
PdfTemplate template = cb.createTemplate(width, height);
template.addImage(img, width, 0, 0, height, 0, 0);
// removed the code that draws lines
return Image.getInstance(template);
}
Instead of lines, you want to draw a PdfPTable, so we add some code where it says // removed the code that draws lines. As documented, adding a table at an absolute position is done with the writeSelectedRows() method:
public Image getWatermarkedImage(PdfContentByte cb, Image img) throws DocumentException {
float width = img.getScaledWidth();
float height = img.getScaledHeight();
PdfTemplate template = cb.createTemplate(width, height);
template.addImage(img, width, 0, 0, height, 0, 0);
PdfPTable table = new PdfPTable(2);
table.setTotalWidth(width);
table.getDefaultCell().setBorderColor(BaseColor.Yellow);
table.addCell("Test1");
table.addCell("Test2");
table.addCell("Test3");
table.addCell("Test4");
table.writeSelectedRows(0, -1, 0, height, template);
return Image.getInstance(template);
}
I adapted one of the many examples in the official documentation (see WatermarkedImages5), and this is the result:
All the functionality you needed to achieve this was available in the documentation. Please read that documentation before you post another question.

Related

Not seeing blank signature field added to PDF

I am replacing TextFields to Signature fields and not able to see these blank signature fields in the generated PDF.
These blank fields will be needed to digitally signed by client at later stages.
/// <summary>
/// Adds a text field to the report that the user can update signatures to the specified location.
/// </summary>
/// <param name="writer">pdfwriter of document.</param>
/// <param name="xPosition">The lower left x position of the text field.</param>
/// <param name="yPosition">The lower left y position of the text field.</param>
/// <param name="width">The width of the text field.</param>
/// <param name="height">The height of the text field.</param>
/// <param name="fieldId"></param>
protected virtual void AddTextField(iTextSharp.text.pdf.PdfWriter writer, String fieldId, float xPosition, float yPosition, float width, float height)
{
Rectangle position = new Rectangle(xPosition, yPosition, xPosition + width, Math.Max(yPosition - height, 0));
iTextSharp.text.pdf.TextField field = new iTextSharp.text.pdf.TextField(writer, position, fieldId);
// Requirement is to change existing textFields to blank Signature fields
// In the method, memoryStream, reader and stamper are not available.
// Below is the textField I need to transform into Signature field.
// field.Text = String.Empty;
// field.Font = FontFactory.GetFont("Arial Narrow").BaseFont;
// field.TextColor = Color.WHITE;
// field.FontSize = 9;
// Not seeing the signature field appear on the pdf.
// Don't know exactly the reason
PdfFormField sig = PdfFormField.CreateSignature(writer);
sig.SetWidget(position, null);
sig.Flags = PdfAnnotation.FLAGS_PRINT;
sig.Put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g"));
sig.FieldName = fieldId;
sig.SetPage();
writer.AddAnnotation(sig);
//Also tried below code
//PdfFormField pfield = PdfFormField.CreateSignature(writer);
//pfield.FieldName = fieldId;
//pfield.SetFieldFlags(PdfAnnotation.FLAGS_PRINT);
//pfield.SetWidget(position, null);
//pfield.SetPage();
//pfield.MKBorderColor = Color.BLACK;
//pfield.MKBackgroundColor = Color.BLUE;
//PdfAppearance tp = PdfAppearance.CreateAppearance(writer, width, height);
//tp.Rectangle(position);
//tp.Stroke();
//pfield.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
//writer.AddAnnotation(pfield);
}
Second quest:
*Do I really need a signature field if - client will add signature text to these field at later stages (using 3rd party tool like DocuSign)? or simple PDFTextFields would really work?
Adding above question with the query as this may be helpful in relating my scenario.
Thanks in advance for the help.
I just tested your code using
public void AddSignatureFieldLikePrashantJha()
{
Document document = new Document();
Stream stream = new FileStream(#"emptySignatureFieldLikePrashantJha.pdf", FileMode.Create);
PdfWriter pdfWriter = PdfWriter.GetInstance(document, stream);
document.Open();
AddTextField(pdfWriter, "Signature", 100, 100, 400, 50);
document.Close();
}
In the result Adobe Reader DC clearly indicated the signature field position by an arrow:
Putting the focus to that field (e.g. by pressing TAB) the field even is given a frame:
Earlier Adobe Reader versions show it even clearer, e.g. 9.5:
Thus, I cannot reproduce that you are
not able to see these blank signature fields in the generated PDF
If you want to have the field area appear somehow more pronounced, you can indeed use a PdfAppearance, e.g.
protected virtual void AddFancySignatureField(iTextSharp.text.pdf.PdfWriter writer, String fieldId, float xPosition, float yPosition, float width, float height)
{
Rectangle position = new Rectangle(xPosition, yPosition, xPosition + width, Math.Max(yPosition - height, 0));
iTextSharp.text.pdf.TextField field = new iTextSharp.text.pdf.TextField(writer, position, fieldId);
PdfFormField sig = PdfFormField.CreateSignature(writer);
sig.SetWidget(position, null);
sig.Flags = PdfAnnotation.FLAGS_PRINT;
sig.Put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g"));
sig.FieldName = fieldId;
sig.SetPage();
PdfAppearance tp = PdfAppearance.CreateAppearance(writer, width, height);
PdfShading radial = PdfShading.SimpleRadial(writer, 0, height / 2, 0, 0, height / 2, width, BaseColor.RED, BaseColor.GREEN);
tp.PaintShading(radial);
sig.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
writer.AddAnnotation(sig);
}
The result looks like this:
Second quest: *Do I really need a signature field if - client will add signature text to these field at later stages (using 3rd party tool like DocuSign)? or simple PDFTextFields would really work?
That depends very much on the exact 3rd party tool used. Some such tools require signature fields, some require a text marker in the content, some want the position given by coordinate...

unable to set background color on iTextSharp signature appearance

Does anyone have any ideas on how to set the background color on the PdfSignatureAppearance rectangle in iTextSharp? I create the PdfSignatureAppearance object and can set its positioning on the page, but the rectangle only has a transparent background. I'm trying to apply a color (any really).
I've tried creating a new iTextSharp.text.Rectangle then setting the rect.BackgroundColor = new BaseColor(System.Drawing.Color.Yellow); That doesn't work. I saw someone else trying to something similar by applying the styles to the layer2 of the signature appearance object. I've tried these with no luck.
PdfTemplate sigAppLayer2 = appearance.GetLayer(2);
sigAppLayer2.SetRGBColorFill(255, 0, 0);
sigAppLayer2.SetGrayFill(2);
sigAppLayer2.BoundingBox.BackgroundColor = new BaseColor(System.Drawing.Color.Yellow);
Anytime I try one of the above styling changes to the layer2 the visible signature disappears on the PDF. If I try applying it to layer 0 or layer 1 then nothing happens. I'm assuming then I'm touching the correct layer (2).
Any ideas? The goal is to just get a background on the signature box vs having it be transparent.
See comment below. I tried this as well setting against layer 2 and layer 0. Both result in a red box, but the signature text is missing.
PdfTemplate sigAppLayer2 = appearance.GetLayer(2);
Rectangle rect = sigAppLayer2.BoundingBox;
PdfTemplate sigAppLayer0 = appearance.GetLayer(0);
sigAppLayer0.SetRGBColorFill(255, 0, 0);
sigAppLayer0.Rectangle(rect.Left, rect.Bottom, rect.Width, rect.Height);
sigAppLayer0.Fill();
You need to draw the rectangle and fill that rectangle with the fill color.
From memory (untested), you need something like this:
PdfTemplate sigAppLayer2 = appearance.GetLayer(2);
Rectangle rect = sigAppLayer2.BoundingBox;
sigAppLayer2.SetRGBColorFill(255, 0, 0);
sigAppLayer2.Rectangle(rect.Left, rect.Bottom, rect.Width, rect.Height);
sigAppLayer2.Fill();
This is the way:
PdfTemplate sigAppLayer2 = appearance.GetLayer(2);
Rectangle rect = sigAppLayer2.BoundingBox;
sigAppLayer2.SetRGBColorFill(255, 0, 0);
sigAppLayer2.Rectangle(rect.Left, rect.Bottom, rect.Width, rect.Height);
sigAppLayer2.Fill();
sigAppLayer2.ResetRGBColorFill();// <--------- you needs this
sigAppLayer2.BeginText() ...etc

Add image to iText dynamically on PDF file

Can some one please help me what is missing in my code, I am trying to add image in to PDF generation
fillFieldValue(stamper.getAcroFields(),agntCertBean);
Image image1 = Image.getInstance(bb);
image1.scaleAbsolute(25f, 25f);
PdfContentByte overContent = stamper.getOverContent(1);
AcroFields form = stamper.getAcroFields();
AcroFields.FieldPosition fldPos = (AcroFields.FieldPosition)
form.getFieldPositions("ProfilePciture");
overContent.addImage(image1);
stamper.close();
reader.close();
Looking at your code without paying too much attending, I see two major mistakes:
[1.] There's something wrong with this line:
AcroFields.FieldPosition fldPos = (AcroFields.FieldPosition)form.getFieldPositions("ProfilePciture");
The getFieldPositions() method returns a List of FieldPosition elements and you're casting that list to a FieldPosition object. That won't work, you need something like this:
AcroFields.FieldPosition fldPos = form.getFieldPositions("ProfilePicture").get(0);
[2.] You get the position of the picture field, but you're not doing anything with it! You're not setting the position of the image!
Remove these two lines:
image1.scaleAbsolute(25f, 25f);
PdfContentByte overContent = stamper.getOverContent(1);
Add these lines after you've obtained the field position:
Rectangle rect = fldPos.position;
image1.scaleToFit(rect.getWidth(), rect.getHeight());
image1.setAbsolutePosition(rect.getLeft(), rect.getBottom());
PdfContentByte overContent = stamper.getOverContent(fldPos.page);
In these lines you scale the image so that it fits the field and you set the coordinates of the image. You also get the PdfContentByte instance for the correct page instead of from the first page.
You may have other errors, but please fix these first!

iTextSharp z-index

I'm using itextSharp to add anotations in a pdf document.
I have a pdf document that already contains an image saved in it, it's a stamp.
So I draw some stroke on this pdf in the stamp and everything is fine when I draw them in my WPF but when I send the pdf by email using iTextSharp for the conversion the line I drawed is now below the stamp.
How I can solve this problem ?
Thank you
The explanation you posted as an answer (BTW, more apropos would have been to edit your question to contain that data) explains the issue.
There are two principal types of objects visible on a PDF page:
the PDF page content;
annotations associated with the page.
The annotations are always displayed above the page content if they are displayed at all.
In your case you add the image to the PDF page content (using OverContent or UnderContent only changes where in relation to other PDF page content material your additions appear). The stamp, on the other hand, most likely is realized by means of an annotation. Thus, the stamp annotation always is above your additions.
If you want to have your additions appear above the stamp, you either have to add your additions as some kind of annotation, too, or you have to flatten the stamp annotation into the page content before adding your stuff.
Which of these varients is better, depends on the requirements you have. Are there any requirements forcing the stamp to remain a stamp annotation? Are there any requirements forcing your additions to remain part of the content? Please elaborate your requirements. As content and annotations have some different properties when displayed or printed, please state all requirements.
And furthermore, please supply sample documents.
So like I said the original pdf have a stamp saved inside it, if I open the pdf with acrobat reader I can move the stamp.
So here my code to write some strokes :
using (var outputStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.Read))
using (var intputStream = new FileStream(pathPdf, FileMode.Open, FileAccess.Read, FileShare.Read))
{
PdfReader reader = new PdfReader(intputStream);
using (var pdfStamper = new PdfStamper(reader, outputStream))
{
foreach (var page in pages)
{
if (page != null && page.ExportedImages.HasItems())
{
PdfContentByte pdfContent = pdfStamper.GetOverContent(page.PageIndex);
Rectangle pageSize = reader.GetPageSizeWithRotation(page.PageIndex);
PdfLayer pdfLayer = new PdfLayer(string.Format(ANNOTATIONNAMEWITHPAGENAME, page.PageIndex), pdfContent.PdfWriter);
foreach (ExporterEditPageInfoImage exportedInfo in page.ExportedImages)
{
Image image = PngImage.GetImage(exportedInfo.Path);
image.Layer = pdfLayer;
if (quality == PublishQuality.Normal || quality == PublishQuality.Medium || quality == PublishQuality.High)
{
float width = (float)Math.Ceiling((image.Width / image.DpiX) * 72);
float height = (float)Math.Ceiling((image.Height / image.DpiY) * 72);
image.ScaleAbsolute(width, height);
float x = (float)(exportedInfo.HorizontalTile * (page.TileSize * (72 / 96d)));
float y = (float)Math.Max(0, (pageSize.Height - ((exportedInfo.VerticalTile + 1) * (page.TileSize * (72 / 96d)))));
image.SetAbsolutePosition(x, y);
}
else
throw new NotSupportedException();
pdfContent.AddImage(image);
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}
pdfStamper.Close();
}
}
So my strokes are saved good in the pdf the problem the stamp is always on top of everything and I think is normal so can I do a workaround for this ?

Raphael-GWT: fill image of a shape (Rect) appears offset. How to resolve this?

I'm wondering about the behavior of {Shape}.attr("fill","url({image.path})").
when applying a fill image to a shape:
public class AppMapCanvas extends Raphael {
public AppMapCanvas(int width, int height) {
super(width, height);
this.hCenter = width / 2;
this.vCenter = height / 2;
...
Rect rect = this.new Rect(hCenter, vCenter, 144, 40, 4);
rect.attr("fill", "url('../images/app-module-1-bg.png')"); // <--
...
}
}
The background image seem to teal accross the canvas behind the shape, thus gets weird positioning (an illustration snapshot is enclosed - i marked the original image borders in red).
This seem to resolve itself in the presence of an animation along a path (a mere path.M(0,0) is sufficiant).
How can i position the fill-image properly in the first place?
The proper way to do this from what I can understand would be to use an SVG pattern declaration to specify the portion and position of the image you would want to use. Then you would use that pattern to fill the rectangle element. Unfortunately, the Raphael javascript library doesn't have support for patterns... so there's no direct way to use an image to fill a rectangle.