[Tex/LaTex] How to add random lines over text as a watermark and anti-OCR

drmwatermark

I would like to add a sort of a watermark to a PDF file produced using LaTeX. I have in mind graphical elements (lines, circles, etc.) that would partially obscure the text on the page. The arrangement (and perhaps the shape and the number of) the elements should be different on every page, and it would be best if it could be derived from a pseudorandom seed given in the document, so different compilations would produce the same arrangement of elements.

As a bonus, I'd like to protect parts of the text from being obscured by those random lines and squiggles – instead of obscuring those parts, the watermarks could pass "under" a white rectangle with them on top, or just not appear where such protected text is. It's not a problem to mark such parts inside the LaTeX document.

My use case is a visible watermark for document tracking, with a very rudimentary anti-OCR feature (since some letters in the text would be obscured). Let me preemptively say that I am well aware of the ability to copy text from PDF, the possibility of retyping the document, etc.

Now the question is where to start looking for a solution – TikZ is able to draw geometric shapes pretty well, but I have no idea how to make them random and different on every page, nor how to protect parts of text… any pointers would be appreciated.

Best Answer

Here's a quick and dirty solution:

\documentclass{article}

\makeatletter
\usepackage{tikz}
\usepackage{everypage}

\pgfmathsetseed{314}

\newlength{\obfobjectsize}
\setlength{\obfobjectsize}{36pt}
\newcommand{\obftext}{obfuscated}

\newcommand{\dontobfuscate}[1]{%
  \ifmmode\let\@dollar=$\else\let\@dollar=\relax\fi
  \vphantom{#1}\smash{\fboxsep=0pt\colorbox{white}{\@dollar #1\@dollar}}%
}

\newcommand{\setrandomcoordinates}{% Places random coordinates (in pt)
  \pgfmathrnd                      % in \a and \b.
  \let\a=\pgfmathresult
  \pgfmathmultiply{\a}{\paperwidth}%
  \let\a=\pgfmathresult
  % 
  \pgfmathrnd
  \let\b=\pgfmathresult
  \pgfmathmultiply{\b}{\paperheight}%
  \let\b=\pgfmathresult
}
\newcommand{\tkzplacerandomline}{
  \setrandomcoordinates
  %
  \pgfmathrand
  \let\c=\pgfmathresult
  \pgfmathmultiply{\c}{\obfobjectsize}%
  \let\c=\pgfmathresult
  % 
  \pgfmathrand
  \let\d=\pgfmathresult
  \pgfmathmultiply{\d}{\obfobjectsize}%
  \let\d=\pgfmathresult
  % 
  \coordinate[xshift=\a,yshift=\b] (a) at (current page.south west);
  \coordinate[xshift=\c,yshift=\d] (b) at (a);
  \draw[ultra thick] (a) -- (b);
}
\newcommand{\tkzplacerandomcircle}{
  \setrandomcoordinates
  %
  \pgfmathrnd
  \let\c=\pgfmathresult
  \pgfmathmultiply{\c}{\obfobjectsize}%
  \let\c=\pgfmathresult
  % 
  \coordinate[xshift=\a,yshift=\b] (a) at (current page.south west);
  \draw[ultra thick] (a) circle (\c pt);
}
\newcommand{\tkzplacerandomnode}{%
  \setrandomcoordinates
  %
  \pgfmathrandominteger{\c}{30}{330}
  %
  \coordinate[xshift=\a,yshift=\b] (a) at (current page.south west);
  \node[rotate=\c] at (a) {\obftext};
}

\newcommand{\placerandomobjects}[2]{%
  \begin{tikzpicture}[overlay,remember picture]
    \foreach \n in {1,2,...,#2} { #1 }
  \end{tikzpicture}%
}

\AddEverypageHook{
\placerandomobjects{\tkzplacerandomline}{100}
\placerandomobjects{\tkzplacerandomcircle}{100}
\placerandomobjects{\tkzplacerandomnode}{100}
}

\makeatother

\begin{document}
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus
elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur
dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id,
vulputate a, magna.  Donec vehicula augue eu neque. Pellentesque
habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla
et lectus vestibulum urna fringilla ultrices. Phasellus eu tellus sit
amet tortor gravida placerat. Integer sapien est, iaculis in, pretium
quis, viverra ac, nunc. \dontobfuscate{Praesent eget sem vel leo ultrices
bibendum}. Aenean faucibus. Morbi dolor nulla, malesuada eu, pulvinar
at, mollis ac, nulla. Cur- abitur auctor semper nulla. Donec varius
orci eget risus. Duis nibh mi, congue eu, accumsan eleifend, sagittis
quis, diam. Duis eget orci sit amet orci dignissim rutrum.

Nam dui ligula, fringilla a, euismod sodales, sollicitudin vel,
wisi. Morbi auctor lorem non justo. Nam lacus libero, pretium at,
lobortis vitae, ultricies et, tellus. Donec aliquet, tortor sed
accumsan bibendum, erat ligula aliquet magna, vitae ornare odio metus
a mi. Morbi ac orci et nisl hendrerit mollis. Suspendisse ut
massa. Cras nec ante. Pellentesque a nulla. Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur ridiculus
mus. Aliquam tincidunt urna.

Nulla ullamcorper vestibulum turpis. Pellentesque cursus luctus
mauris.  Nulla malesuada porttitor diam. Donec felis erat, congue non,
volutpat at, tincidunt tristique, libero. Vivamus viverra fermentum
felis. \dontobfuscate{$E=m(a^2+b^2)$} Donec nonummy pellentesque
ante. Phasellus adipiscing semper elit. Proin fermentum massa ac
quam. Sed diam turpis, molestie vitae, placerat a, molestie nec,
leo. Mae- cenas lacinia. Nam ipsum ligula, eleifend at, accumsan nec,
suscipit a, ipsum.  Morbi blandit ligula feugiat magna. Nunc eleifend
consequat lorem. Sed lacinia nulla vitae enim. Pellentesque tincidunt
purus vel magna. Integer non enim.  Praesent euismod nunc eu
purus. Donec bibendum quam in tellus. Nullam cur- sus pulvinar
lectus. Donec et mi. Nam vulputate metus eu enim. Vestibulum
pellentesque felis eu massa.

Quisque ullamcorper placerat ipsum. Cras nibh. Morbi vel justo vitae
lacus tincidunt ultrices. Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. In hac habitasse platea dictumst. Integer tempus
convallis augue. Etiam facilisis.
\begin{displaymath}
  \dontobfuscate{E=m(a^2+b^2)}
\end{displaymath}
Nunc elementum fermentum
wisi. Aenean placerat. Ut imperdiet, enim sed gravida sollicitudin,
felis odio placerat quam, ac pulvinar elit purus eget enim.  Nunc
vitae tortor. Proin tempus nibh sit amet nisl. Vivamus quis tortor
vitae risus porta vehicula.
\end{document}

It is not very elegant, and especially the \dontobfuscate command is really very simple; it will work in horizontal mode (and generate a box, so it will be not breakable and the spaces will have their natural width, which will look ugly unless (a) only individual words are put in it or (b) the text is set ragged right or something similar; it will also work in math mode, but in a very primitive fashion (suitable for e.g. simple symbols). But it works as a proof of concept, and making it more versatile is now a question of some tweaking. Have fun!

PS. Not to mention that the "drm" tag might be considered a bit, say, offensive by some people in this community;).

Edit: as cjorssen mentioned in the comment, this needs two-pass compilation, since it uses the remember picture mechanism of tikz.