24

I'm using Tikz to design the cover of a book and I need to do something like this :Bacgkround clips to text

I've tried to use some tricks given here but it did nothing.

I'm actually using the following code:

\makeatletter
\renewcommand{\maketitle}{%
\begin{titlepage}%
\pagestyle{empty}%
\begin{tikzpicture}[overlay,remember picture]%


% Logo
\node[opacity=1,inner sep=0pt] at ([yshift=-0.09\paperheight]current page.north){\includegraphics[width=0.35\paperwidth]{logo.eps}};

% Document title
\node (booktitle) at ([yshift=-.45\paperheight]current page.north) [above, text width=.8\paperwidth, font=\fontsize{40pt}{43pt}\selectfont, color=covertext, align=center] {\bfseries\@title};%


\end{tikzpicture}%
\end{titlepage}%
\setcounter{footnote}{0}%
}
\makeatother

Could you help me please.

John Doe
  • 467
  • 4
  • 10

3 Answers3

20

Solution without TikZ

Using text as clip path is supported by package pdfrender if pdfTeX (or LuaTeX) is running in PDF mode.

\pdfsave and \pdfrestore saves and restores the current graphics state, thus that the clipping ends after \pdfrestore. Since the graphics state include the current transfer matrix (e.g., the current point on the PDF page), the command pair must be used on the same TeX location. Otherwise the TeX coordinate system and the PDF coordinate system would go out of sync.

Full example:

\documentclass{article}
\usepackage{graphicx}
\usepackage{pdfrender}
\usepackage{tgheros}
\usepackage{varwidth}

\newcommand*{\TextImage}[2]{%
  \sbox0{%
    \sffamily
    \bfseries
    \begin{varwidth}{\linewidth}%
      \uppercase{\ignorespaces#1\ifhmode\unskip\fi}%
    \end{varwidth}%
  }%
  \mbox{%
    \pdfsave
    % Set clip path
    \pdfrender{TextRenderingMode=Clip}%
    \rlap{%
      \copy0 %
    }%
    % Now the image or whatever is provided in #2 is used.
    \rlap{%
      \def\width{\wd0 }%
      \def\depth{\dp0 }%
      \def\height{\ht0 }%
      \def\totalheight{\dimexpr\ht0+\dp0\relax}%
      \raisebox{-\dp0}{#2}%
    }%
    \pdfrestore
    % Inform TeX about the text dimensions
    \phantom{\copy0}%
  }%
}

\begin{document}
  \TextImage{%
    This text clips the\\
    background image%
  }{%
    \includegraphics[
      width=\width,
      height=\totalheight,
      viewport=0 0 {10mm} {5mm},
    ]{bg.pdf}%
  }
\end{document}

Result

The background image bg.pdf was generated with:

\documentclass[tikz]{standalone}
\begin{document}
  \begin{tikzpicture}
    \pgfmathsetseed{10000}
    \foreach \i in {1, ..., 500} {
      \pgfmathsetmacro\colred{rnd}
      \pgfmathsetmacro\colgreen{rnd}
      \pgfmathsetmacro\colblue{rnd}
      \definecolor{col}{rgb}{\colred,\colgreen,\colblue}
      \pgfmathsetlengthmacro\rad{.1mm + 10mm*rnd/sqrt(\i)}
      \fill[col] (rnd, rnd) circle[radius=\rad];
    }
    \pgfresetboundingbox
    \useasboundingbox (0, 0) (1, 1);
  \end{tikzpicture}
\end{document}
Heiko Oberdiek
  • 271,626
17

This is a slightly tweaked solution based on Mark Wibrow's answer.

It adds the fit library so that the front node (the one with the text) stretches to cover the background image without having to set the size manually.

This is the image source (place it in your Tex folder where the main document is, and rename it vegetation).

Output

figure 1

Code

\documentclass[12pt,a4paper]{article}
\usepackage[margin=.5in]{geometry}
\usepackage{tikz}
\usepackage{lmodern}
\usepackage{graphicx}

\usetikzlibrary{fit,fadings}

\makeatletter
\tikzset{
  outline text/.style={
    execute at begin node={%
      \pgfsetfillopacity{0}%
      \pgfsetlinewidth{\pgflinewidth}%
      \pgfsetstrokecolor{#1}%
      \special{pdf:literal 1 Tr }%      
    },
  },
  knockout text fading/.code={%
    \tikz@addmode{%
      % Interrupt the picture to create a fading.
      \pgfinterruptpicture%
        \let\tikz@atbegin@node=\relax%
        \begin{tikzfadingfrompicture}[name=.]
          \node [node contents=, #1,text=transparent!100, fill=transparent!0];%
          \xdef\fadingboundingbox{{\noexpand\pgfpoint{\the\pgf@picminx}{\the\pgf@picminy}}%
            {\noexpand\pgfpoint{\the\pgf@picmaxx}{\the\pgf@picmaxy}}}%
          \expandafter\pgfpathrectanglecorners\fadingboundingbox%
          \pgfusepath{discard}%
         \end{tikzfadingfrompicture}%
       \endpgfinterruptpicture%
       % Make the fading happen.
       \def\tikz@path@fading{.}%
       \tikz@mode@fade@pathtrue%
       \tikz@fade@adjustfalse%
       \pgfpointscale{0.5}{\expandafter\pgfpointadd\fadingboundingbox}%
       \def\tikz@fade@transform{shift={(\the\pgf@x,\the\pgf@y)}}%
    }%
    \tikzset{#1}% 
  }
} 
\makeatother

\begin{document}
\begin{figure}
    \centering
\begin{tikzpicture}[line join=round]

    \node (image) at (0,0) {\includegraphics[scale=.6]{vegetation}};
    \node[font=\sffamily\bfseries\fontsize{50}{40}\selectfont,text width=18cm, align=center,outline text=white, fit=(image.south west)(image.north east),       knockout text fading={
         fill=white, draw=white,
         node contents={THIS TEXT CLIPS THE BACKGROUND IMAGE}}];

\end{tikzpicture}
\end{figure}
\end{document}
Alenanno
  • 37,338
11

In TikZ you can use tikzfadingfrompicture from fadings library to clip using text.

In the following example I use a shaded rectangle in place of your image.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fadings}

\begin{document}

% the clipping text
\begin{tikzfadingfrompicture}[name=title]
  \node [text=transparent!0, text width=0.7\paperwidth, align=center, font=\fontfamily{ptm}\bfseries\scshape, scale=3]
    {This text clips the\\ background immage};
\end{tikzfadingfrompicture}

% use it to clip your image
\begin{tikzpicture}
  \node[scope fading=title,fit fading=false] (0,0) {
    % \includegraphics[width=0.7\paperwidth]{logo.eps}
    \begin{tikzpicture}
      \shade[left color=red, right color=blue] (0,0) rectangle (15,5);
    \end{tikzpicture}
  };
\end{tikzpicture}
\end{document}

enter image description here

Note: There are other related topics like this answer or this one.

Kpym
  • 23,002