Akhil Parameswaran
Akhil Parameswaran

Reputation: 25

I want to watermark a pdf file without creating another pdf file

I want to convert an image to PDF and add a watermark to it. I used iTextSharp to convert it. I successfully converted the image file to pdf but I'm not able to add watermark to it without creating another pdf file.

The code below creates a PDF file and also adds custom attributes, function watermarkpdf is used to add watermark and pdfname is given as the arguement

foreach (string filenm in Images)
    using (var imageStream = new FileStream(filenm, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        doc.NewPage();

        iTextSharp.text.Image jpeg = iTextSharp.text.Image.GetInstance(filenm);
        float width = doc.PageSize.Width;
        float height = doc.PageSize.Height;
        jpeg.ScaleToFit(width,height);
        doc.Add(jpeg);
    }
    doc.AddHeader("name", "vijay");
    watermarkpdf(pdfname);

The watermarkpdf function is given below.

PdfReader pdfReader = new PdfReader(txtpath.Text+"\\pdf\\" + pdfname);
FileStream stream = new FileStream(txtpath.Text + pdfname,FileMode.Open);
PdfStamper pdfStamper = new PdfStamper(pdfReader, stream);
for (int pageIndex = 1; pageIndex <= pdfReader.NumberOfPages; pageIndex++)
{
    Rectangle pageRectangle = pdfReader.GetPageSizeWithRotation(pageIndex);
    PdfContentByte pdfData = pdfStamper.GetUnderContent(pageIndex);
    pdfData.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 40);
    PdfGState graphicsState = new PdfGState();
    graphicsState.FillOpacity = 0.4F;
    pdfData.SetGState(graphicsState);
    pdfData.SetColorFill(BaseColor.BLUE);
    pdfData.BeginText();
    pdfData.ShowTextAligned(Element.ALIGN_CENTER, "SRO-Kottarakkara", pageRectangle.Width / 2, pageRectangle.Height / 2, 45);
    pdfData.EndText();
}
pdfStamper.Close();
stream.Close();

Upvotes: 1

Views: 2919

Answers (1)

Chris Haas
Chris Haas

Reputation: 55417

iTextSharp doesn't support "in-place editing" of files, only reading existing files and creating new files. The problem is that it would have to write to something that is being written to which could be very problematic.

However, instead of using a file you can create your image in a MemoryStream, grab the bytes from that and pipe that to the PdfReader, all with minimal changes to your code. All of the PDF writing functions that take files actually work with the abstract Stream class and which MemoryStream inherits from so they can be used interchangeably. Below is some basic code that should show you what I'm talking about. I don't have an IDE currently so there might be a typo or two but for the most part it should work.

//Image part
//We will dump the bytes from the memory stream to the variable below later
byte[] bytes;
using (MemoryStream ms = new MemoryStream()){
  Document doc = new Document(PageSize.LETTER);
  PdfWriter writer = PdfWriter.GetInstance(doc, ms);
  doc.Open();
  //foreach (string filenm in Images)
  //...
  doc.Close();
  //Dump the bytes, make sure to use ToArray() and not GetBuffer()
  bytes = ms.ToArray();
}

//Watermark part
//Read from our bytes
PdfReader pdfReader = new PdfReader(bytes);
FileStream stream = new FileStream(txtpath.Text + pdfname,FileMode.Open);
//...

Upvotes: 2

Related Questions