Add Image to a PDF digitally signed with itextSharp - pdf

I'd like to put an image into a digitally signed PDF. if I do it using the usual way, the signature is broken. But with Acrobat it's possible to add an annotation stamp to a signed PDF and the signature is not broken.
Googgling I've found an example of how to do that:
http://itext.2136553.n4.nabble.com/Digital-Signature-Corrupted-after-adding-watermark-image-td4657457.html
I've translate it to c# but without success:
using (Stream inputPdfStream = new FileStream("test.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream inputImageStream = new FileStream("grafo.jpg", FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream outputPdfStream = new FileStream("result.pdf", FileMode.Create, FileAccess.Write, FileShare.None))
{
var reader = new PdfReader(inputPdfStream);
var stamper = new PdfStamper(reader, outputPdfStream);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(0, 0);
PdfTemplate template = PdfTemplate.CreateTemplate(stamper.Writer, image.Width, image.Height);
template.AddImage(image);
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(350, 250, 350 + image.Width, 250 + image.Height);
PdfAnnotation annotation = PdfAnnotation.CreateStamp(stamper.Writer, rect, null, Guid.NewGuid().ToString());
annotation.SetAppearance(PdfName.N, template);
stamper.AddAnnotation(annotation, 1);
stamper.Close();
}
When I open the PDF with Acrobat, signature is broken.
Some idea of how to do that with iText?
Thank's

The PdfStamper must be created in append mode.
var stamper = new PdfStamper(reader, outputPdfStream, '\0', true);

Related

How to write byte[] to PDF document using itextSharp

I have a byte[] and I want to write byte[] to PDF document. I have seen Paragraph, ShowText methods to print text but I don't know how to pass byte[]. In the below code, I want to write fileBytes to PDF. How to do that?
BaseFont f_cb = BaseFont.CreateFont("c:\\windows\\fonts\\calibrib.ttf", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
BaseFont f_cn = BaseFont.CreateFont("c:\\windows\\fonts\\calibri.ttf", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
byte[] fileBytes = File.ReadAllBytes(#"D:\196836f7-9cf5-4044-b11e-2e3d06888c43.pdf");
using (FileStream fs = new FileStream(#"D:\result_196836f7-9cf5-4044-b11e-2e3d06888c43.pdf", FileMode.Create))
{
Document document = new Document(PageSize.LETTER, 25, 25, 30, 30);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
// Add meta information to the document
document.AddAuthor("John");
document.AddCreator("itestSharp demo");
document.AddKeywords("ItextSharp tutorial");
document.AddSubject("Steps to write byte[] to PDF using c#");
document.AddTitle("Steps to write byte[] to PDF using c#");
document.Open();
PdfContentByte cb = writer.DirectContent;
cb.SetFontAndSize(f_cb, 16);
cb.BeginText();
cb.SetTextMatrix(25, 400);
cb.ShowText("Hello World");
cb.EndText();
document.Close();
writer.Close();
fs.Close();
}

How to add html checkbox,radiobutton,textbox in pdf using itextstarp?

How to add html checkbox,radiobutton,textbox in pdf using itextstarp.Am using this code.
StringWriter stringWriter = new StringWriter();
MemoryStream stream = new System.IO.MemoryStream();
var viewData = ViewData;
ViewEngineResult viewEngineResult = ViewEngines.Engines.FindView(ControllerContext, "ABCDFORM", null);
ViewContext viewContext = new ViewContext(ControllerContext, viewEngineResult.View, viewData, new TempDataDictionary(), stringWriter);
viewEngineResult.View.Render(viewContext, stringWriter);
// Get the view HTML string
string htmlToConvert = stringWriter.ToString();
StringReader sr = new StringReader(htmlToConvert);
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 0f, 0f);
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, stream);
pdfDoc.Open();
XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
pdfDoc.Close();
string fileName = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
return File(stream.ToArray(), "application/pdf", string.Format("{0}.pdf", fileName));
In ABCDFORM is a my view,I am working on MVC.and
am create ABCDFORM as html file.
I need add html checkbox,radiobutton in pdf

how can I reduce pdf size using pdfbox

I want to compress output PDF. The code below output was so biger than original file. Can I use compress option?
PDDocument doc = new PDDocument();
InputStream in = new FileInputStream(f);
BufferedImage bimg = ImageIO.read(in);
PDPage page = new PDPage(PDRectangle.A4);
doc.addPage(page);
PDImageXObject pdImageXObject = JPEGFactory.createFromImage(doc, bimg, 0.03f);
PDPageContentStream contentStream = new PDPageContentStream(doc, page, AppendMode.APPEND, true);
contentStream.close();
doc.save(outfile);
doc.close();

Generated pdf using iText. Textfields show data after field focus

I'm using iText to generate a pdf with textfields populated with data, from an ASP.NET web form. For some reason, when the pdf is generated, the textfields show Empty, but when I put the cursor on the field, the text shows. If I click somewhere else, then the text in the textfield disappears again. This is the code, adding a textfield called "Field_0_0". The text "hello1" is set to the textfield, but it doesn't display until clicking the textbox. The only way to get the text in the textfield is by typing something, and then the text stays there after losing focus.
byte[] templatebytes = null;
//Dim doc As New Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 35)
Document doc = new Document(iTextSharp.text.PageSize.LETTER);
MemoryStream stream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc, stream);
doc.Open();
Paragraph para = new Paragraph("This is my first paragraph");
Phrase pharse = new Phrase("This is my first phrase");
Chunk chunk_ = new Chunk("This is my first chunk");
doc.Add(para);
doc.Add(pharse);
doc.Add(chunk_);
doc.Close();
templatebytes = stream.ToArray();
//==============================================================================================================================================
Stream stream2 = new MemoryStream(templatebytes);
byte[] finalbytes = null;
using (MemoryStream outputPdfStream = new MemoryStream())
{
iTextSharp.text.pdf.PdfReader pdfReader = new iTextSharp.text.pdf.PdfReader(stream2);
iTextSharp.text.pdf.PdfStamper pdfStamper = new iTextSharp.text.pdf.PdfStamper(pdfReader, outputPdfStream);
TextField tf1 = new TextField(writer, new iTextSharp.text.Rectangle(20, 20, 200, 100), "Field_0_0");
tf1.DefaultText = " ";
tf1.Options = TextField.MULTILINE | TextField.VISIBLE;
tf1.TextColor = BaseColor.BLACK;
tf1.FontSize = 10;
tf1.BorderWidth = 1;
tf1.BorderColor = BaseColor.BLUE;
pdfStamper.AddAnnotation(tf1.GetTextField(), 1);
pdfStamper.Close();
finalbytes = outputPdfStream.ToArray();
}
//====================================== set data ========================================
Stream stream3 = new MemoryStream(finalbytes);
byte[] finalbytes3 = null;
using (MemoryStream outputPdfStream = new MemoryStream())
{
iTextSharp.text.pdf.PdfReader pdfReader = new iTextSharp.text.pdf.PdfReader(stream3);
iTextSharp.text.pdf.PdfStamper pdfStamper = new iTextSharp.text.pdf.PdfStamper(pdfReader, outputPdfStream);
//Set fields with data
iTextSharp.text.pdf.AcroFields form = pdfStamper.AcroFields;
IDictionary<string, iTextSharp.text.pdf.AcroFields.Item> fields = form.Fields;
string value = "Hello1"; //$"Line1{Environment.NewLine}Line2";
form.SetField("Field_0_0", value); //$"Line1{Environment.NewLine}Line2"
pdfStamper.Close();
finalbytes3 = outputPdfStream.ToArray();
}
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=GeneratedPDF.pdf");
Response.AddHeader("Content-Length", finalbytes3.Length.ToString());
Response.BinaryWrite(finalbytes3);
Response.End();
Hopefully I explained this right. I can't find a solution online to solve this problem.
Thanks
Set property of pdfStamper follow this:
pdfStamper.AcroFields.GenerateAppearances = false;

itextsharp form name and saving pdf

I am using itextsharp in ASP.NET. We populate a PDF with fields that are taken from one of our online forms. I need to change the way we handle the documents - we need to be able to use some of the fields as the name of the document(firstname-lastname.pdf), and to save that PDF into a directory. Here is the code I am using now:
PdfStamper ps = null;
DataTable dt = BindData();
if (dt.Rows.Count > 0)
{
PdfReader r = new PdfReader(new RandomAccessFileOrArray("http://www.example.com/Documents/ppd-certificate.pdf"), null);
ps = new PdfStamper(r, Response.OutputStream);
AcroFields af = ps.AcroFields;
af.SetField("fullName", dt.Rows[0]["fullName"].ToString());
af.SetField("presentationTitle", dt.Rows[0]["presentationTitle"].ToString());
af.SetField("presenterName", dt.Rows[0]["presenterFullName"].ToString());
af.SetField("date", Convert.ToDateTime(dt.Rows[0]["date"]).ToString("MM/dd/yyyy"));
ps.FormFlattening = true;
ps.Close();
}
PdfStamper and PdfWriter both use the generic Stream class so instead of Response.OutputStream you can use a FileStream or a MemoryStream
This example writes directly to disk. Set testFile to whatever you want, I'm using the desktop here
//Your file path here:
var testFile = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
using (var fs = new FileStream(testFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
PdfReader r = new PdfReader(new RandomAccessFileOrArray("http://www.example.com/Documents/ppd-certificate.pdf"), null);
var ps = new PdfStamper(r, fs);
//..code
}
This next example is my preferred method. It creates a MemoryStream, then creates a PDF inside of it and finally grabs the raw bytes. Once you've got raw bytes you can both write them to disk AND Response.BinaryWrite() then.
byte[] bytes;
using (var ms = new MemoryStream()) {
PdfReader r = new PdfReader(new RandomAccessFileOrArray("http://www.example.com/Documents/ppd-certificate.pdf"), null);
var ps = new PdfStamper(r, ms);
//..code
bytes = ms.ToArray();
}
//Your file path here:
var testFile = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
//Write to disk
System.IO.File.WriteAllBytes(testFile, bytes);
//Send to HTTP client
Response.BinaryWrite(bytes);