Recursive AI

Add an image to a PDF in C#

All onepdf recipes

Add the image to the document with AddPngImage or AddJpegImage, then draw it on a page with DrawImage at a position and size in points. The program below puts a logo in the top right corner of the IRS Form W-9, a public PDF you can download to try it.

Terminal
dotnet new console -o AddImage && cd AddImage
dotnet add package RecursiveAI.OnePdf --version 1.14.0
curl -LO https://www.irs.gov/pub/irs-pdf/fw9.pdf
curl -o logo.png https://recursiveai.org/assets/brand/icon-512.png

Put this in Program.cs and run dotnet run:

C#
using OnePdf;
 
using PdfDocument doc = PdfDocument.Open("fw9.pdf",
    new PdfOpenOptions { AllowEditing = true });
 
// Add the image once; it can then be drawn on any number of pages.
// or AddJpegImage
PdfCreatedImage logo = doc.AddPngImage(File.ReadAllBytes("logo.png"));
 
PdfPage page = doc.Pages[0];
PdfRectangle size = page.MediaBox;
Console.WriteLine($"Page 1 is {size.Width:0} x {size.Height:0} points");
Console.WriteLine($"logo.png is {logo.Width} x {logo.Height} pixels");
 
// 24 points wide (1/3 inch), height from the image's aspect ratio.
double width = 24, height = width * logo.Height / logo.Width;
 
using (PdfPageContentBuilder b = page.BeginContent())   // over the existing content
{
    b.DrawImage(logo, 552, 764, width, height);   // x, y of its lower left corner
    b.Commit();                                 // nothing is written before Commit
}
 
doc.Save("fw9-logo.pdf");
Console.WriteLine("Saved fw9-logo.pdf");
Text
Page 1 is 612 x 792 points
logo.png is 512 x 512 pixels
Saved fw9-logo.pdf

The logo now sits in the top right corner of page 1, a third of an inch square, in the margin above the form, with its transparent background kept. The page’s own content is unchanged.

Positions and sizes

  • Coordinates are in points, 72 to the inch, from the lower left corner of the page, with y going up. A US Letter page is 612 × 792 points and A4 is 595 × 842. page.MediaBox gives the size of any page.
  • DrawImage stretches the image to the box you give it, so compute one side from the other to keep the aspect ratio, as above.
  • An image prints at its pixel width divided by the box width in inches: 512 pixels across 1/3 inch is 1,536 dpi, far more than print needs, so scale large images down before adding them to keep the file small.
  • page.BeginContent(PdfContentPlacement.Underlay) draws under the page’s content instead of over it.
  • To put the same image on every page, call DrawImage in a loop over doc.Pages. The image is stored once.

Limits

  • JPEG and PNG only. AddJpegImage embeds a JPEG’s bytes as they are, without recompressing (baseline and progressive; arithmetic-coded and lossless JPEGs are refused). AddPngImage stores a PNG losslessly, its alpha channel as a soft mask. Convert other formats first, or pass raw pixels to AddRawImage.
  • Rotated pages. Content you draw isn’t turned with a page that has /Rotate set, so the image appears rotated. Check page.Rotate, or use a stamp, which compensates.
  • Signed PDFs. Adding an image changes the page, so do it before signing.

For a logo or text on every page, faint and rotated, see Add a watermark to a PDF. To pull images out of a PDF, see Extract images from a PDF. Text, lines and shapes are drawn with the same builder: see Content creation.