Linux – Overlay text in PDF via command line

ghostscriptlinuxpdfpdftk

The following command produced the result of the following image using convert, where an overlay box containing the letter "A" was layered over the PDF:

convert online_gauss.pdf -fill white -undercolor '#00000080'
-pointsize 40 -gravity South -annotate +0+5 ' A ' online_gauss_annot.pdf

Desired result

However, convert rasterizes the source. Since I would like to keep the original PDF format (vectorial) for publishing, is there a simple way of achieving this type of annotation via command line over a single PDF image?
I would be happy just with the letter, even in the bottom left corner.

I've seen some examples using Ghostscript, pdftk (stamp) but they involve several intermediate steps that are difficult to get right for different sized PDF images.

Best Answer

Well, I've come up with a solution using TikZ within a crafted LaTex document. The result is not exactly the same, but I think it is even nicer:

Solution output

This required having a tex document with placeholders that will be replaced by the arguments to a sh script.

% file: add_legend.tex

\documentclass{standalone}
\usepackage{graphicx}

\usepackage{tikz}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LaTeX Overlay Generator - Annotated Figures v0.0.1
% Created with (omitted http) ff.cx/latex-overlay-generator/
% If this generator saves you time, consider donating 5,- EUR! :-)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\annotatedFigureBoxCustom{bottom-left}{top-right}{label}{label-position}{box-color}{label-color}{border-color}{text-color}
\newcommand*\annotatedFigureBoxCustom[8]{\draw[#5,thick,rounded corners] (#1) rectangle (#2);\node at (#4) [fill=#6,thick,shape=circle,draw=#7,inner sep=4pt,font=\huge\sffamily,text=#8] {\textbf{#3}};}
%\annotatedFigureBox{bottom-left}{top-right}{label}{label-position}
\newcommand*\annotatedFigureBox[4]{\annotatedFigureBoxCustom{#1}{#2}{#3}{#4}{white}{white}{black}{black}}
\newcommand*\annotatedFigureText[4]{\node[draw=none, anchor=south west, text=#2, inner sep=0, text width=#3\linewidth,font=\sffamily] at (#1){#4};}
\newenvironment {annotatedFigure}[1]{\centering\begin{tikzpicture}
\node[anchor=south west,inner sep=0] (image) at (-0.75,-0.75) { #1};\begin{scope}[x={(image.south east)},y={(image.north west)}]}{\end{scope}\end{tikzpicture}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}  

  \begin{annotatedFigure}           
        {\includegraphics[width=1.0\linewidth]{_image_}}    
        \annotatedFigureBox{0,0}{0.000,0.0}{_letter_}{0,0}%bl
    \end{annotatedFigure}  

\end{document}

And the sh script:

#!/bin/sh
# Call this script with at least 2 parameters, for example
# sh scriptname <image_file> <letter_of_legend> 

cat add_legend.tex | sed "s/_image_/$1/g" | sed "s/_letter_/$2/g" | pdflatex

#rename output to match <letter_of_legend>_<image_file> format
mv texput.pdf $2_$1 

#clean up
rm texput.*

exit 0

Finnaly, by calling:

$> ./legend.sh online_gauss.pdf A

the output drawn in "A_online_gauss.pdf"!

Related Question