Annotations created with iTextSharp not showing up - c#

I have a PDF of a blank 1-page MS Word doc. I want to add a text box to it. Code as follows:
void addAnnotation()
{
string filename = #"C:\Users\userID\Documents\Visual Studio 2013\Projects\PDFConverterTester\TestAddSrc.pdf";
string destFile = #"C:\Users\userID\Documents\Visual Studio 2013\Projects\PDFConverterTester\TestAddDest.pdf";
PdfReader pdfReader = new PdfReader(filename);
FileStream stream = new FileStream(destFile, FileMode.Create);
PdfStamper pdfStamper = new PdfStamper(pdfReader, stream);
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(100,100, 100, 100);
PdfWriter pdfWriter = pdfStamper.Writer;
PdfAnnotation annot = PdfAnnotation.CreateStamp(pdfWriter, rect, "XYZABC add rect", "new rectangle");
pdfStamper.AddAnnotation(annot, 1);
pdfStamper.Close();
}
When I open TestAddDest.pdf, it's blank, just like the source PDF, and the file size is the same, so I'm assuming the annotation has not been added. How can I add this text box?
Edit:
Source PDF: http://docdro.id/jAOpxr3
Destination PDF: http://docdro.id/gOaHsQm

The reason the PDF is blank is because the Rectangle is zero width and zero height :
iTextSharp.text.Rectangle rect = new
iTextSharp.text.Rectangle(100,100, 100, 100);
Put a breakpoint on that line or:
Console.WriteLine("W: {0}, H: {1}", rect.Width, rect.Height);
output:
W: 0, H: 0
Try something like this, which places the Rectangle at the top of the page:
Rectangle rect = new Rectangle(20, 700, 400, 776);
Destination PDF:

Related

Poor image quality after added to PDF with itextsharp

I want to create a portrait gallery with some photos. In order to achieve this, I add everything I need in a panel and then I get the visual of this panel to add it in a PDF.
My problem is that I managed to create the PDF containing the image, but it is bad quality.
Example 1
Example 2
We see that the outline of peoples is not clear, while in the original photos the outline is very clear.
iTextSharp.text.Document doc = new iTextSharp.text.Document();
panelTombi.AutoScrollPosition = new Point(0, 0);
panelTombi.AutoSize = true;
panelTombi.Refresh();
int width = panelTombi.Width;
int height = panelTombi.Height;
Bitmap MemoryImage = new Bitmap(width, height);
panelTombi.DrawToBitmap(MemoryImage, new System.Drawing.Rectangle(0, 0, width, height));
iTextSharp.text.Image image1 = iTextSharp.text.Image.GetInstance((System.Drawing.Image)MemoryImage, System.Drawing.Imaging.ImageFormat.Jpeg);
image1.ScaleToFit(doc.PageSize);
image1.SetAbsolutePosition(0, PageSize.A4.Height - image1.ScaledHeight - doc.TopMargin);
MemoryImage.Save(Path.GetDirectoryName(sfd.FileName) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(sfd.FileName) + ".jpeg");
//Save pdf file
PdfWriter.GetInstance(doc, new FileStream(sfd.FileName, FileMode.Create));
doc.Open();
doc.Add(image1);
doc.Close();
As you can see, the image is also saved.
Could you tell me how to fix this image quality problem on the PDF file?
Thank you

iTextSharp offsetting image

I am generating a byte array image and in order to convert it to pdf I am adding that image into a PDF document. the image size is exactly 812, 1015 DPI and even though I have document with the same size the image is being offset by about an inch (the red bar represents this offset) because of this I am missing about the same amount on the other side. Why is the PDF adding the image in this way. Here is the code:
var resizedImage = new Bitmap(812, 1015);
var drawResizedImage = Graphics.FromImage(resizedImage);
drawResizedImage.DrawImage(img, 0, 0, 812, 1015);
resizedImage.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
return getPDFDocument(memoryStream);
private byte[] getPDFDocument(MemoryStream inputImageStream)
{
MemoryStream workStream = new MemoryStream();
iTextSharp.text.Document document = new iTextSharp.text.Document(new iTextSharp.text.Rectangle(812, 1015));
PdfWriter.GetInstance(document, workStream).CloseStream = false;
document.Open();
iTextSharp.text.Image pdfImage = iTextSharp.text.Image.GetInstance(inputImageStream.ToArray());
document.Add(pdfImage);
document.Close();
byte[] byteInfo = workStream.ToArray();
workStream.Write(byteInfo, 0, byteInfo.Length);
workStream.Position = 0;
return workStream.ToArray();
}
This is producing this
Add this line to your code block
pdfImage.SetAbsolutePosition(0, 0);
You should see this:
document.Open();
iTextSharp.text.Image pdfImage = iTextSharp.text.Image.GetInstance(inputImageStream.ToArray());
pdfImage.SetAbsolutePosition(0, 0);
document.Add(pdfImage);
document.Close();
That should give you the desired positioning.

Convert Image to Pdf using itextsharp with spacing on top

Im doing a image to pdf program.
I want to set the size of the image as the size of the pdf and a extra space on top with 50
i tried this code
using (var imageStream = new FileStream(imagelocation, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var image = Image.GetInstance(imageStream);
Document document = new Document(new Rectangle(image.Width, image.Height), 0, 0, 0, 0);
using (var stream = new FileStream(pdfOutput, FileMode.Create, FileAccess.Write, FileShare.None))
{
PdfWriter.GetInstance(document, stream);
document.Open();
document.Add(image);
document.Close();
}
}
but the problem is it doesn't have a top margin,
when i try this code
Document document = new Document(new Rectangle(image.Width, image.Height), 0, 50, 50, 0);
it crop a part of the image for the space. how can i make this work?
By setting the document margins like "0, 50, 50, 0" you are also setting a margin-right, that might not be what you want in this case. The margin top is the correct way to get some space above the image.
Alternatively you can add some empty lines to your document before adding the image, e.g.: document.Add(new Paragraph(Chunk.NewLine))
You can use image.ScaleToFit() and pass in something like document.PageSize.Height and document.PageSize.Width to make that image fit your page.
this is my solution. i didn't realize that this simple code will work
Document document = new Document(new Rectangle(image.Width, image.Height + 150), 0, 0, 150, 0);

Not able to write multiple annotation images in itextsharp

Here i am trying to add to images as overlay on text.so i used pushbutton and annotations. but i can write only one image.not able to write second image onwards.Please help me
PdfReader reader1 = new PdfReader(Path);
FileStream fs = new FileStream(OutLocation, FileMode.Create, FileAccess.Write,FileShare.None);
PdfStamper stamper = new PdfStamper(reader1, fs);
PushbuttonField fld = new PushbuttonField(stamper.Writer,
new iTextSharp.text.Rectangle(315, 400, 210, 250), "Test ");
fld.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
string Img = path + "RedSlash.png";
iTextSharp.text.Image jpeg = iTextSharp.text.Image.GetInstance(Img);
jpeg.ScaleToFit(100, 200);
fld.Image = jpeg;
stamper.AddAnnotation(fld.Field, 1);
fld1 = new PushbuttonField(stamper.Writer,
new iTextSharp.text.Rectangle(500, 500, 210, 250), "Test ");
fld1.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
iTextSharp.text.Image jpeg1 = iTextSharp.text.Image.GetInstance(Img);
jpeg1.ScaleToFit(100, 200);
fld1.Image = jpeg1;
stamper.AddAnnotation(fld1.Field, 1);
Answer 1 to your question was: make sure the different fields have different names. You fixed this based on my comment and it worked.
Answer 2 to your question is: don't use form fields to add images, just add the images "the normal way". You asked me for a code sample, I'm giving you a chapter of my book: Working
with existing PDFs. In this chapter, you'll find some examples involving the PdfStamper class. You can find the C# version of these examples here.
Some code:
using (PdfStamper stamper = new PdfStamper(reader, ms)) {
Image img = Image.GetInstance(imagePath);
img.SetAbsolutePosition(0, 0);
int n = reader.NumberOfPages;
PdfContentByte foreground;
for (int i = 1; i <= n; i++) {
foreground = stamper.GetOverContent(i);
foreground.AddImage(img);
}
}

ITextSharp insert text to an existing pdf

The title sums it all.
I want to add a text to an existing PDF file using iTextSharp, however i can't find how to do it anywhere in the web...
PS: I cannot use PDF forms.
I found a way to do it (dont know if it is the best but it works)
string oldFile = "oldFile.pdf";
string newFile = "newFile.pdf";
// open the reader
PdfReader reader = new PdfReader(oldFile);
Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
// open the writer
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
// the pdf content
PdfContentByte cb = writer.DirectContent;
// select the font properties
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252,BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.DARK_GRAY);
cb.SetFontAndSize(bf, 8);
// write the text in the pdf content
cb.BeginText();
string text = "Some random blablablabla...";
// put the alignment and coordinates here
cb.ShowTextAligned(1, text, 520, 640, 0);
cb.EndText();
cb.BeginText();
text = "Other random blabla...";
// put the alignment and coordinates here
cb.ShowTextAligned(2, text, 100, 200, 0);
cb.EndText();
// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
// close the streams and voilá the file should be changed :)
document.Close();
fs.Close();
writer.Close();
reader.Close();
I hope this can be usefull for someone =) (and post here any errors)
In addition to the excellent answers above, the following shows how to add text to each page of a multi-page document:
using (var reader = new PdfReader(#"C:\Input.pdf"))
{
using (var fileStream = new FileStream(#"C:\Output.pdf", FileMode.Create, FileAccess.Write))
{
var document = new Document(reader.GetPageSizeWithRotation(1));
var writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
for (var i = 1; i <= reader.NumberOfPages; i++)
{
document.NewPage();
var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
var importedPage = writer.GetImportedPage(reader, i);
var contentByte = writer.DirectContent;
contentByte.BeginText();
contentByte.SetFontAndSize(baseFont, 12);
var multiLineString = "Hello,\r\nWorld!".Split('\n');
foreach (var line in multiLineString)
{
contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, line, 200, 200, 0);
}
contentByte.EndText();
contentByte.AddTemplate(importedPage, 0, 0);
}
document.Close();
writer.Close();
}
}
This worked for me and includes using OutputStream:
PdfReader reader = new PdfReader(new RandomAccessFileOrArray(Request.MapPath("Template.pdf")), null);
Rectangle size = reader.GetPageSizeWithRotation(1);
using (Stream outStream = Response.OutputStream)
{
Document document = new Document(size);
PdfWriter writer = PdfWriter.GetInstance(document, outStream);
document.Open();
try
{
PdfContentByte cb = writer.DirectContent;
cb.BeginText();
try
{
cb.SetFontAndSize(BaseFont.CreateFont(), 12);
cb.SetTextMatrix(110, 110);
cb.ShowText("aaa");
}
finally
{
cb.EndText();
}
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
}
finally
{
document.Close();
writer.Close();
reader.Close();
}
}
Here is a method that uses stamper and absolute coordinates showed in the different PDF clients (Adobe, FoxIt and etc. )
public static void AddTextToPdf(string inputPdfPath, string outputPdfPath, string textToAdd, System.Drawing.Point point)
{
//variables
string pathin = inputPdfPath;
string pathout = outputPdfPath;
//create PdfReader object to read from the existing document
using (PdfReader reader = new PdfReader(pathin))
//create PdfStamper object to write to get the pages from reader
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(pathout, FileMode.Create)))
{
//select two pages from the original document
reader.SelectPages("1-2");
//gettins the page size in order to substract from the iTextSharp coordinates
var pageSize = reader.GetPageSize(1);
// PdfContentByte from stamper to add content to the pages over the original content
PdfContentByte pbover = stamper.GetOverContent(1);
//add content to the page using ColumnText
Font font = new Font();
font.Size = 45;
//setting up the X and Y coordinates of the document
int x = point.X;
int y = point.Y;
y = (int) (pageSize.Height - y);
ColumnText.ShowTextAligned(pbover, Element.ALIGN_CENTER, new Phrase(textToAdd, font), x, y, 0);
}
}
Here is a method To print over images:
taken from here.
Use a different layer for your text you're putting over the images, and also make sure to use the GetOverContent() method.
string oldFile = "FileWithImages.pdf";
string watermarkedFile = "Layers.pdf";
// Creating watermark on a separate layer
// Creating iTextSharp.text.pdf.PdfReader object to read the Existing PDF Document
PdfReader reader1 = new PdfReader(oldFile);
using (FileStream fs = new FileStream(watermarkedFile, FileMode.Create, FileAccess.Write, FileShare.None))
// Creating iTextSharp.text.pdf.PdfStamper object to write Data from iTextSharp.text.pdf.PdfReader object to FileStream object
using (PdfStamper stamper = new PdfStamper(reader1, fs))
{
// Getting total number of pages of the Existing Document
int pageCount = reader1.NumberOfPages;
// Create New Layer for Watermark
PdfLayer layer = new PdfLayer("Layer", stamper.Writer);
// Loop through each Page
for (int i = 1; i <= pageCount; i++)
{
// Getting the Page Size
Rectangle rect = reader1.GetPageSize(i);
// Get the ContentByte object
PdfContentByte cb = stamper.GetOverContent(i);
// Tell the cb that the next commands should be "bound" to this new layer
cb.BeginLayer(layer);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.RED);
cb.SetFontAndSize(bf, 100);
cb.BeginText();
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Some random blablablabla...", rect.Width / 2, rect.Height / 2, - 90);
cb.EndText();
// Close the layer
cb.EndLayer();
}
}

Categories

Resources