My goal is to add company logo to every page of an existing pdf(not watermark).
Due to pdf file and logo specifics, I can only place the logo on top of the pdf content(not underneath) and the logo has to support transparency.
One more limitation is I have to use .NET Core.
Posting this with an answer, because I could not find a clear solution.
Suggestions/corrections/improvements are welcome.
Hope someone finds this useful.
The newest iTextSharp library to support .NET Core is iText7 however I cannot use it legitemately; neither making my code open source, nor purchasing the licence is an option for me. Therefore I use old, third party library:
Install-Package iTextSharp.LGPLv2.Core
Latest version, the one I'm using, at the time of this post is 1.3.2
Following usings are required
using System;
using System.Drawing.Imaging;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
To acheve image transparency in pdf, image has to be opened in a correct format
var preImage = System.Drawing.Image.FromFile(imagePath);
var image = Image.GetInstance(preImage, ImageFormat.Png);
When adding the image, it is also important to not select the image to be inline
canvas.AddImage(image);//do not put .AddImage(image, true);
Here is all the code
var imagePath = "logo.png";
var pdfPath = "edit_this.pdf";
//load pdf file
var pdfBytes = File.ReadAllBytes(pdfPath);
var oldFile = new PdfReader(pdfBytes);
//load image
var preImage = System.Drawing.Image.FromFile(imagePath);
var image = Image.GetInstance(preImage, ImageFormat.Png);
preImage.Dispose();
//optional: if image is wider than the page, scale down the image to fit the page
var sizeWithRotation = oldFile.GetPageSizeWithRotation(1);
if (image.Width > sizeWithRotation.Width)
image.ScalePercent(sizeWithRotation.Width / image.Width * 100);
//set image position in top left corner
//in pdf files, cooridinates start in the left bottom corner
image.SetAbsolutePosition(0, sizeWithRotation.Height - image.ScaledHeight);
//in production, I use MemoryStream
//I put FileStream here to test the code in console application
using (var newFileStream = new FileStream("with_logo.pdf", FileMode.Create))
{
//setup PdfStamper
var stamper = new PdfStamper(oldFile, newFileStream);
//iterate through the pages in the original file
for (var i = 1; i <= oldFile.NumberOfPages; i++)
{
//get canvas for current page
var canvas = stamper.GetOverContent(i);
//add image with pre-set position and size
canvas.AddImage(image);
}
stamper.Close();
}
This code works with local files.
In my (real world) case, I receive pdf files as Base64 string, add a logo from local storage, convert it back to Base64 string and output it on a web-page.
I open the image as PNG forcefully(hardcoded) because I control what extension does the logo have. If necessary you can dynamicaly set the image format.