7

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.

Bruno Silva
  • 101
  • 1
  • 5
  • 1
    I think pdfstamp is a good match for your problem. Perhaps you should detail your problems with it in case there is a solution. – meuh Oct 03 '15 at 18:26
  • Thanks, but that requires generating a separate pdf file with the desired letter and then stamping it at the bottom; the generated pdf should also have proportional dimensions regarding the source. – Bruno Silva Oct 04 '15 at 12:20
  • @meuh I found pdfstamp thanks to your comment, and it is just what I need for MY problem, thanks! The only question is I don't seem to be able to overlay UTF8 text, even when doublechecking to have a font with Unicode support. Any ideas? – Gnudiff Aug 17 '17 at 15:15
  • @Gnudiff I see the same problem, but I don't have an answer at the moment. Perhaps if you post a new question someone might know. – meuh Aug 17 '17 at 18:37
  • @meuh I ended up using pdftk and applying pdf over pdf – Gnudiff Aug 18 '17 at 11:14

2 Answers2

7

For people that do not want to install a texlive distribution, you may prefer cpdf as explained here. However since cpdf has a strange license for commercial use, I tried to find an alternative. Here is one (you need to install enscript, ps2pdf and (pdftk or qpdf)).

The idea is just to use enscript to create a .ps from a text, then you convert this .ps into a .pdf using ps2pdf, and then you stack it on top of the original pdf with pdftk or qpdf...).

pdtfk version:

echo "I will be stamped on top of the page" | enscript -B -f Courier-Bold16 -o- | ps2pdf - | pdftk input.pdf stamp - output output.pdf

qpdf version:

If you want the text to repeat on all pages:

tmpfile=$(mktemp) && echo "I will be stamped on top of the page" | enscript -B -f Courier-Bold16 -o- | ps2pdf - "$tmpfile" && qpdf out_merge.pdf --overlay "$tmpfile" --repeat=1-z -- out_oneline.pdf

if you just want to put it on the first page:

tmpfile=$(mktemp) && echo "I will be stamped on top of the page" | enscript -B -f Courier-Bold16 -o- | ps2pdf - "$tmpfile" && qpdf out_merge.pdf --overlay "$tmpfile" -- out_oneline.pdf

See the documentation for more options.

NB: mktemp is just used to create a temporary file to provide a one-liner solution, since qpdf does not accept input from stdin

Unfortunately, I'm not sure to know how to set the position of the text, for not it's always on top left in a4 pages...

tobiasBora
  • 4,041
  • 4
  • 23
  • 35
3

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"!

Bruno Silva
  • 101
  • 1
  • 5
  • I have a lot of output text, I change a bit the script but is the same cat add_legend.tex | sed "s/_image_/$1/g" | sed "s/_letter_/$2/g" > texput.tex and pdflatex -interaction batchmode texput.tex – inye Jul 25 '17 at 16:55