Of all the methods for adding an image to a pdf document that I tried (and I tired a lot of them, including most of the rest of those mentioned on this page), the only one that consistently produced high-quality output is a method using LaTeX, which I describe below. You don't need to know anything about LaTeX beyond what I will say here. You don't even have to have a working LaTeX installation on your computer: you can use the completely free online LaTeX editor Overleaf.
This is a viable solution provided you are willing to get rid of all interactive features in your pdf document: fillable form fields, highlights, comments, links, bookmarks, etc. If your original pdf document already has some interactive content, you will first need to produce a 'plain' version of it, i.e. a version that doesn't have any interactive features.
You can produce a 'plain' pdf by e.g. printing your original pdf document to a new pdf file (see here). This way, whatever e.g. interactive forms you filled out will be present as regular text in the printed, 'plain' pdf. Now you will be able to use LaTeX to add a picture to this 'plain' pdf. The resulting pdf file (produced by LaTex) will also be 'plain'. (It might be possible to restore the interactive features using something called pax
, see e.g. here, but I haven't tried it myself.)
Why LaTeX-based solutions cannot preserve interactive features of the original pdf document is explained here.
If your input pdf is not 'plain', all the content in the interactive features will be ignored by LaTeX. So if e.g. you have put some text into a fillable form field, the document produced by LaTeX would not show it—it would show a blank.
Apart from the limitation of not being able to include interactive features in the output, this solution is potentially very powerful, allowing e.g. rescaling and rotating of images, and programmatic insertion of multiple images on multiple pages. (Though I will not provide details for the last one, I will give an indication of how it can be done).
In addition, this solution is otherwise unlimited, completely free, and open source. And, as I said, it should introduce no degradation in quality compared to your input files.
(Besides the method described here, there are actually many ways to do this in LaTeX; see here.)
Procedure
The goal is to take a 'plain' ten-page pdf file, in our case one called 'sample_pdf_letter_format.pdf', and add a certain png image in the middle of page 5. That image will be this png of a 'blue globe', which has a transparent background:

(I've downloaded that png from here.)
I will describe the procedure assuming you are working with pdf in letter format. Adapting this to A4 format requires only minimal modification; at any rate, I will be providing scripts for both.
I will explain everything using Overleaf, but of course everything can be done using a LaTeX installation on your own computer, or using some other online LaTeX editor.
I have enabled sharing for a 'project' on Overleaf. This project contains sample files on which I will explain what to do. You will be able to view and download all the files, and also to 'compile' any files whose names end with`.tex'.
However, you will not be able to upload any files or to modify the existing ones.
In order to add your own images to your own pdf files, all you need to do is sign up for a free Overleaf account and upload all the relevant files to your project (including the relevant .tex
file from my project). Alternatively, use a LaTeX installation on your own computer.
So, click here.
Once you click on that link, you should be seeing the Overleaf workspace, like this:

On the left you can see a bunch of files. One of them should be highlighted. Make sure that it is 'main_letter_format.tex' (click on it if it is not). Once that file is highlighted, its contents should appear in the middle part of the screen. On the right part of the screen, you should see a nicely formatted document with the title 'A sample pdf document'; if you do not, press the button 'Recompile' that's above this part of the screen. In the end, the page should look like the above screencap.
On the right side of the screen, scroll the document down to page 5. You should see this:

The blue globe,
,
is the png that is superimposed on the pdf.
You can download the whole output pdf (with the png added to it) by clicking on the following icon, to the right of the 'Recompile' button:

Now let's see what this 'project' is actually doing.
Our original pdf, to which the image is to be added, is 'sample_pdf_letter_format.pdf'. The image to be added is called 'blue_globe.png'. That's the 'blue globe' I showed above, with a transparent background.
These two files were uploaded to Overleaf using the upload button on the left-hand part of the screen (you won't see it right now—you would need to be logged on to your own Overleaf project to be able to upload files):

Now let's look at the file 'main_letter_format.tex', which contains the actual LaTeX code that accomplishes the addition of the image to the pdf document. (For completeness, I have also reproduced the content of that file here; see below.)
Note that the names of the original pdf document ('sample_pdf_letter_format.pdf') and of the image file ('blue_globe.png') are entered in lines 12 and 13:
\newcommand{\originalPDFfilename}{sample_pdf_letter_format.pdf}
\newcommand{\imagename}{blue_globe.png}
Assume we want to add the image file on page 5 of the pdf document. Then we first include, without modification, pages 1-4 of the original pdf file. This is done in line 16:
\includepdf[pages=1-4]{\originalPDFfilename}
.
Similarly, we will include pages 6-10 at the end, in line 27:
\includepdf[pages=6-last]{\originalPDFfilename}
.
(Note that you can use the keyword last
instead of explicitly saying which page is last.)
Now we deal with page 5 in lines 17-26.
The page number is specified in line 26:
,pages=5]{\originalPDFfilename}
.
Note that line 20 is 'commented out' by starting it with '%':
%\includegraphics[scale=1]{gridlines_letter_bp.png} %comment out before producing the final version
If you remove the initial '%' and recompile, you will see grid lines on page 5. (To be able to actually remove the initial '%', you need to be logged into your own Overleaf account and do it in your own copy of this file.) Such grid lines may be helpful to position the image on the page. This is what they look like:

At present, the spacing of the grid lines is in units of 'bp', which are PostScript points (1/72 of an inch). I have also produced (see below for an explanation of how) grid line files with spacing in inches ('gridlines_letter_in.png') and millimeters ('gridlines_letter_mm.png'). For A4 format, I produced grid line files with spacings in bp and in millimeters. If you prefer some of these other grid lines, just substitute their respective file names in line 20. But make sure to again comment out line 20 (and recompile) before you download the final document, so that the grid lines do not appear in it.
The actual insertion of the image happens in lines 22-24:
\begin{textblock*}{0in}[0,1](-15pt+300bp,11in-500bp)
\includegraphics[width=1in,origin=c,angle=0]{\imagename}
\end{textblock*}
If you look at the screenshot with grid lines (above), you will see that the png containing the 'blue globe' is 72 bp ( = 1 in) wide, extending from 300 bp to 372 bp.
The width is specified in width=1in
in line 23, and the height is scaled so that the aspect ratio is the same as in the original image. Alternatively, you could provide the height (height=1in
), and then the width will be scaled. You can also provide both width and height (generally, this will distort the image, but sometimes that is useful). Another way to resize the image is by using the command 'scale='; for example, 'scale=0.1' makes the image size 10% of its original size. Finally, one can rotate the image by specifying angle
in degrees (the rotation is about the center of the image). For even more details, see here.
That takes care of the size and rotation of the image. Its placement on the page is done in line 22:
\begin{textblock*}{0in}[0,1](-15pt+300bp,11in-500bp)
.
The {0in}
is irrelevant for us.
The [0,1]
part says that what we will be positioning—the 'reference point' of the image—is the lower-left corner of the image.
The default reference point is the upper-left corner. The two numbers in brackets specify by how much, in units of width and height of the image, you want to displace the reference point. So [0.2,0.7]
would mean that the reference point is 20% of the image width to the right, and 70% of the image height below, the upper-left corner.
Now comes -15pt+300bp,11in-500bp
. The -15pt and 11in are offsets. The meaning of the latter one is clear: that's the height of letter-sized paper. On the other hand, I don't know where the -15pt comes from; I found out its value by experimenting.
The unit 'pt' is the 'TeX point', equal to 1/72.27 inch, whereas the 'bp' is 1/72 inch. In Adobe InDesign, the pt is called the 'traditional printer point', see here.
In the end, if you put
\begin{textblock*}{0in}[0,1](-15pt+0bp,11in-0bp)
then the blue globe will appear in the lower-left corner of the page.
Therefore, -15pt+300bp,11in-500bp
means that the reference point of the image (which we have set to be its lower-left corner) is 300 bp to the right from the left edge of the page, and 500 bp above the lower edge of the page (as you can verify on the screenshot with grid lines).
Why '11in-500bp'? LaTeX likes to measure things from the upper left corner, but the grid lines that I have all have their origin at the lower left. Thus, if we want to be 500 bp above the lower edge, we need to put 11in-500bp; putting just 500bp would instead place the reference point 500 bp below the upper edge of the page.
More images on more pages
If you want to include more than one image on page 5, for each extra image you would need to add, starting in line 25, another block like that in lines 22-24 (one block for each extra image). Of course, instead of \imagename you'd use the names of the other images, instead of 300bp and 500bp you'd use the appropriate coordinates for the new images, and instead of 'width=1in' and 'angle=0' you'd use the widths and angles appropriate for those images.
If you want to add the same image(s) to e.g. pages 5-7, then you'd change line 26 to read
,pages=5-7]{\originalPDFfilename}
and line 27 to read
includepdf[pages=8-last]{\originalPDFfilename}
.
If the pages on which you want to add images are not consecutive, then you'd need to produce separate commands for each page. For example, imagine you want to add the same blue globe (in the same place) to all even-numbered pages. At present, within LaTex, I only know how to do it using 'brute force', i.e.
\includepdf[pages=1]{\originalPDFfilename}
\includepdf[pagecommand= {…},pages=2]{\originalPDFfilename}
\includepdf[pages=3]{\originalPDFfilename}
\includepdf[pagecommand= {…},pages=4]{\originalPDFfilename}
…
Here …
in pagecommand= {…}
stands for the block in lines 22-24.
Of course, one can certainly write a script (in unix bash, or in python, or in perl, or whatever) that will programmatically make an appropriate .tex file.
A more elegant (and potentially more powerful) option is to switch the compiler from pdfLaTeX to LuaLaTex, which enables one to add scripts in the Lua scripting language directly to the .tex file. In Overleaf, the change of the compiler is done like this: Menu->Compiler->LuaLaTeX. The LuaLaTeX will compile all standard LaTeX files normally (in particular, our 'main_letter_format.tex' will compile normally, albeit more slowly), but it additionally allows you to (among other things) add code in the Lua scripting language. Using Lua code, one should be able to do programmatically things like the above. (At least I assume Lua scripting would enable one to do this, based on examples such as those here; I actually have zero experience with Lua scripts.)
Modifications for A4 format
Click on 'main_A4_format.tex'. You should be able to compile it by clicking on the 'Recompile' button. The only differences are that one should replace letterpaper
by a4paper
in lines 1 and 2, and one should replace 11in
by 297mm
in lines 19 and 22.
And that's it: all you have to do is supply your own source document, your own image, and your own specifications for the image size, orientation and position.
The LaTeX codes
For completeness, here is the content of the file 'main_letter_format.tex'. The modifications for A4 format are as explained above.
\documentclass[letterpaper]{article}
\usepackage[letterpaper,left=0in,right=0in,top=0in,bottom=0in]{geometry}
\usepackage{graphicx}
\usepackage{pdfpages}
\usepackage[absolute,overlay]{textpos}
\usepackage{calc}
\begin{document}
\newcommand{\originalPDFfilename}{sample_pdf_letter_format.pdf}
\newcommand{\imagename}{blue_globe.png}
\includepdf[pages=1-4]{\originalPDFfilename}
\includepdf[pagecommand=
{
\begin{textblock*}{0in}[0,1](-15pt+0in,11in)
%\includegraphics[scale=1]{gridlines_letter_bp.png} %comment out before producing the final version
\end{textblock*}
\begin{textblock*}{0in}[0,1](-15pt+300bp,11in-500bp)
\includegraphics[width=1in,origin=c,angle=0]{\imagename}
\end{textblock*}
}
,pages=5]{\originalPDFfilename}
\includepdf[pages=6-last]{\originalPDFfilename}
\end{document}
The grid lines were produced using this code (which I found here):
\documentclass[letterpaper]{article}
\usepackage{xcolor}
\usepackage[grid, gridunit=bp, gridcolor=blue!40, subgridcolor=blue!20]{eso-pic}
\begin{document}
\thispagestyle{empty}
\mbox{} %need to have *something* on a page to render it, so we put an empty box of zero width
\end{document}
Once the pdf with the grid lines is produced, you should convert it to a png image file with white replaced by transparency. This can be done using the free program GIMP (GNU Image Manipulation Program):
- Open the pdf page containing the grid lines in GIMP. You can right-click on it and select 'Open With', and then click on 'GNU Image Manipulation Program'.
- You will be prompted to import pdf. Click the 'Import' button.
- Make sure there is a transparent layer: Layer->Transparency->Add Alpha Channel. In fact, 'Add Alpha Channel' should be greyed out, which means that the alpha channel (i.e. the transparent layer) is already present. If so, exit this dialog by clicking anywhere else on the screen. If 'Add Alpha Channel' is not greyed out, click on it.
- Colors->Color to Alpha… . In the new window dialog, make sure the 'Color' field is set to white, that the 'Transparency threshold' is 0, and that the 'Opacity threshold' is 1. If so, click 'OK'.
- File->Export As… . Make sure you change the extension of the name to '.png'. Click 'Export' button. A new dialog window will appear; click 'Export' in that window, too.