Bad size image in pdf created with itextsharp - c#

I have a problem to create a pdf with itextsharp from images in .tiff.
Here is some code :
iTextSharp.text.Document d = new iTextSharp.text.Document();
PdfWriter pw = PdfWriter.GetInstance(d, new FileStream(filename, FileMode.Create));
d.Open();
PdfContentByte cb = pw.DirectContent;
foreach (Image img in imgs)
{
d.NewPage();
d.SetPageSize(new iTextSharp.text.Rectangle(0, 0, img.Width, img.Height));
iTextSharp.text.Image timg = iTextSharp.text.Image.GetInstance(img, iTextSharp.text.BaseColor.WHITE);
timg.SetAbsolutePosition(0, 0);
cb.AddImage(timg);
cb.Stroke();
}
d.Close();
It creates the pdf with two pages but the image on the first page is to big.The page have the size of the image but it zoom an the bottom left corner of the image.
It does that only with the tiff image, if I take png, it works fine.
Any solution?

Thanks to the comment of mkl, I found it.
Set the page size (SetPageSize) before the new page command (NewPage)

use like this
string[] validFileTypes = {"tiff"};
string ext = System.IO.Path.GetExtension(FileUpload1.PostedFile.FileName);
bool isValidFile = false;
if (!isValidFile)
{
Label.Text = "Invalid File. Please upload a File with extension " +
string.Join(",", validFileTypes);
}
else
{
string pdfpath = Server.MapPath("pdf");
Document doc = new Document(PageSize.A4, 0f, 0f, 0f, 0f);
PdfWriter.GetInstance(doc, new FileStream(pdfpath + "/Images.pdf", FileMode.Create));
doc.Open();
string savePath = Server.MapPath("images\\");
if (FileUpload1.PostedFile.ContentLength != 0)
{
string path = savePath + FileUpload1.FileName;
FileUpload1.SaveAs(path);
iTextSharp.text.Image tiff= iTextSharp.text.Image.GetInstance(path);
tiff.ScaleToFit(doc.PageSize.Width, doc.PageSize.Height);
tiff.SetAbsolutePosition(0,0);
PdfPTable table = new PdfPTable(1);
table.AddCell(new PdfPCell(tiff));
doc.Add(table);
}
doc.Close();
}

Related

Add watermark on top of form fields

I have this code that will add a watermark on each page:
string watermarkLocation = AppDomain.CurrentDomain.BaseDirectory + "Watermark.png";
Document document = new Document();
PdfReader pdfReader = new PdfReader(fileLocation);
PdfStamper stamp = new PdfStamper(pdfReader, new FileStream(fileLocation.Replace(".pdf", "_marked.pdf"), FileMode.Create));
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(watermarkLocation);
img.ScaleToFit(document.PageSize);
img.SetAbsolutePosition(0, 100);
PdfContentByte waterMark;
for (int page = 1; page <= pdfReader.NumberOfPages; page++)
{
waterMark = stamp.GetOverContent(page);
waterMark.AddImage(img);
}
stamp.FormFlattening = true;
stamp.Close();
return fileLocation.Replace(".pdf", "_marked.pdf");
But on PDFs that have textboxes, the image will go behind the textbox/form. I thought flattening the file will fix this, but it does not work.
I used a full image as a test but the watermark in the end will have transparency.
Here's the final code I'm using. As my comment mentioned, there's basically 2 readers/stamps, one to flatten the file and another to add the watermark.
Flatten file:
private byte[] FlattenPdfFormToBytes(PdfReader reader)
{
var memStream = new MemoryStream();
var stamper = new PdfStamper(reader, memStream) { FormFlattening = true };
stamper.Close();
return memStream.ToArray();
}
Add Watermark (which will call FlattenPdfFormToBytes):
public string AddWatermark(string fileLocation)
{
string watermarkLocation = AppDomain.CurrentDomain.BaseDirectory + "Watermark.png";
Document document = new Document();
PdfReader pdfReader = new PdfReader(fileLocation);
PdfReader pdfFlatten = new PdfReader(FlattenPdfFormToBytes(pdfReader)); // The secret sauce is this!!!
PdfStamper stamp = new PdfStamper(pdfFlatten, new FileStream(fileLocation.Replace(".pdf", "_marked.pdf"), FileMode.Create));
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(watermarkLocation);
img.ScaleToFit(document.PageSize);
img.SetAbsolutePosition(0, 100);
PdfContentByte waterMark;
for (int page = 1; page <= pdfFlatten.NumberOfPages; page++)
{
waterMark = stamp.GetOverContent(page);
waterMark.AddImage(img);
}
stamp.Close();
return fileLocation.Replace(".pdf", "_marked.pdf");
}

Placing Images and Text in Specific (Absolute) Locations Using iTextSharp

I am generating a PDF using iTextSharp and there is dynamic content in the middle of the page which is pushing the bottom part of my PdfPTable down too far. Sometimes even off the bottom of the page onto another page.
Would it be possible to position the bottom PdfPTable in a way that it would not get pushed down when the table above it needs more vertical space?
Here is my solution.
Views\Home\Index.cshtml:
<h2>Create PDF</h2>
#Html.ActionLink("Create the PDF", "CreatePDF", "Home")
</div>
HomeController.cs:
public ActionResult Index()
{
return View();
}
public FileStreamResult CreatePDF()
{
Stream fileStream = GeneratePDF();
HttpContext.Response.AddHeader("content-disposition", "inline; filename=MyPDF.pdf");
var fileStreamResult = new FileStreamResult(fileStream, "application/pdf");
return fileStreamResult;
}
private Stream GeneratePDF()
{
var rect = new Rectangle(288f, 144f);
var document = new Document(rect, 10, 10, 10, 10);
document.SetPageSize(PageSize.LETTER.Rotate());
MemoryStream memoryStream = new MemoryStream();
PdfWriter pdfWriter = PdfWriter.GetInstance(document, memoryStream);
document.Open();
////////////////////////
//Place Image in a Specific (Absolute) Location
////////////////////////
Image myImage = Image.GetInstance(Server.MapPath("../Content/BI_logo_0709.png"));
myImage.SetAbsolutePosition(45, 45);
//[dpi of page]/[dpi of image]*100=[scale percent]
//72 / 200 * 100 = 36%
//myImage.ScalePercent(36f);
myImage.ScalePercent(36f);
document.Add(myImage);
////////////////////////
//Place Text in a Specific (Absolute) Location
////////////////////////
//Create a table to hold everything
PdfPTable myTable = new PdfPTable(1);
myTable.TotalWidth = 200f;
myTable.LockedWidth = true;
//Create a paragraph with the text to be placed
BaseFont bfArialNarrow = BaseFont.CreateFont(Server.MapPath("../Content/ARIALN.ttf"), BaseFont.CP1252, BaseFont.EMBEDDED);
var basicSmaller = new Font(bfArialNarrow, 10);
var myString = "Hello World!" +
Environment.NewLine +
"Here is more text." +
Environment.NewLine +
"Have fun programming!";
var myParagraph = new Paragraph(myString, basicSmaller);
//Create a cell to hold the text aka paragraph
PdfPCell myCell = new PdfPCell(myParagraph);
myCell.Border = 0;
//Add the cell to the table
myTable.AddCell(myCell);
//Add the table to the document in a specific (absolute) location
myTable.WriteSelectedRows(0, -1, 550, 80, pdfWriter.DirectContent);
pdfWriter.CloseStream = false;
document.Close();
memoryStream.Position = 0;
return memoryStream;
}

PDF official paper format

I did generate a pdf file from jpg images. But the jpg images have the size of an official paper. When I open the pdf, the image is too big. I need that the pdf document is in official paper size. Any solution? (panel1 has the size of offical paper. I need that this size is equal of offical paper's size)
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "PDF Files|*.pdf";
string fileName = string.Empty;
saveFileDialog1.FileName = "name.pdf";
btnGerarPDF.Visible = false;
using (Bitmap bitmap = new Bitmap(panel1.ClientSize.Width,
panel1.ClientSize.Height))
{
panel1.DrawToBitmap(bitmap, panel1.ClientRectangle);
bitmap.Save("C:\\" + (nPaginasPDF + 1) + ".bmp", ImageFormat.Bmp);
}
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
fileName = saveFileDialog1.FileName;
Document doc = new Document();
PdfWriter.GetInstance(doc, new FileStream(fileName, FileMode.Create));
doc.Open();
for (int iCnt = 0; iCnt < nPaginasPDF+1; iCnt++)
{
iTextSharp.text.Image image1 = iTextSharp.text.Image.GetInstance("C:\\" + (iCnt + 1) + ".bmp");
image1.ScalePercent(75f);
doc.NewPage();
doc.Add(image1);
}
doc.Close();
}
You can set the pagesize when you create the document:
Document doc = new Document(PageSize.A4);

how to change position of added image in pdf using iTextSharp

I want to change the Image position to be in the top right of the pdf as a logo , this code make my image in the top left and some text wrote on it :
string oldFile = #"D:\Source pdf\Source.pdf";
string newFile = #"D:\Result pdf\Result.pdf";
string imagepath = #"D:\Source pdf\Myiamge.jpg";
Console.WriteLine("iText Demo");
PdfReader reader = new PdfReader(oldFile);
Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
iTextSharp.text.Image instanceImg = iTextSharp.text.Image.GetInstance(imagepath);
document.Add(instanceImg);
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.DARK_GRAY);
cb.SetFontAndSize(bf, 8);
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
document.Close();
fs.Close();
writer.Close();
reader.Close();

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