[Tex/LaTex] color text by using an image, so that the color isn’t flat

colorfilltikz-pgf

I'm using tikz to attempt to make a book cover, and I have a "wallpaper" image that looks like leather (not that I've handled that many leather-bound books). I'm using the node command to place text over the top of it, but none of the colors I've experimented with look decent.

Can I use an image of gold-leaf as the fill/stroke for the text? Or for that matter, for the path lines as well?

I've tried googling for this, but I can't figure out a set of keywords non-generic enough to pull back useful results.

Best Answer

You can "color" the text by anything, including external graphics. This is possible with the fadings library, which has been used e.g. here and here. I downloaded your graphics and called it GoldLeaf.jpg. This graphics gets used in the macro \ShadeText, which does the path fading and adjusts the size of the graphics to fit the text. If you want to use the result in a tikzpicture, use a \savebox as illustrated in the second example.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fadings,calc}
\newcommand{\ShadeText}[2][]{%
\begin{tikzfadingfrompicture}[name=temp]
\node[transparent!0] {#2};
\end{tikzfadingfrompicture}%
\tikz[baseline=(X.base)]{\node[inner sep=0pt,outer sep=0pt] (X)
{\phantom{#2}};
\path[path fading=temp,fit fading=false,overlay] let 
 \p1=($(X.north east)-(X.south west)+(0.3,0.3)$) in (X.center)
 node{\includegraphics[width=\x1,height=\y1]{GoldLeaf.jpg}};}%
}
\newsavebox\WhatEver
\begin{document}
\ShadeText{\sffamily\Large\bfseries I'm a title}

\bigskip
\savebox\WhatEver{\ShadeText{\sffamily\Large\bfseries I'm a title}}
\begin{tikzpicture}
 \fill (0,0) rectangle (6,3) node[midway,scale=2]{\usebox\WhatEver};
\end{tikzpicture}
\end{document}

enter image description here

In case you do not want to modify the aspect ratio of the picture, you may use the following instead.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fadings,calc}
\newcommand{\ShadeText}[2][]{%
\begin{tikzfadingfrompicture}[name=temp]
\node[transparent!0] {#2};
\end{tikzfadingfrompicture}%
\tikz[baseline=(X.base)]{\node[inner sep=0pt,outer sep=0pt] (X)
{\phantom{#2}};
\path[overlay]  node[opacity=0] (img) {\includegraphics{GoldLeaf.jpg}}
  [path fading=temp,fit fading=false,overlay] 
  let \p1=($(X.north east)-(X.south west)+(0.3,0.3)$),
  \p2=($(img.north east)-(img.south west)+(0.3,0.3)$) in
   (X.center)  node{\pgfmathsetmacro{\myscale}{max(\x1/\x2,\y1/\y2)}%
  \includegraphics[scale=\myscale]{GoldLeaf.jpg}};
 }%
}
\newsavebox\WhatEver
\begin{document}
\ShadeText{\sffamily\Large\bfseries I'm a title}

\bigskip
\savebox\WhatEver{\ShadeText{\sffamily\Large\bfseries I'm a title}}
\begin{tikzpicture}
 \fill (0,0) rectangle (6,3) node[midway,scale=2]{\usebox\WhatEver};
\end{tikzpicture}
\end{document}

enter image description here

ADDENDUM: Of course you can use this beyond \node objects. This is a very quickly written environment that illustrates it. The body of the environment is the stuff you want to "color", the main argument the name of the graphics file that you are going to use for the "coloring" (what is the technically correct term for that?), and the optional argument some pgf keys whose usage gets illustrated. To complete this addendum, the key fading transform that I learned from this very nice answer, was instrumental. It also benefited from a comment by samcarter, who pointed out that the golden leaf looks almost as beautiful as the fur of a marmot. ;-)

\documentclass{article}
\usepackage{environ}
\usepackage{tikz}
\usepackage{tikzlings}
\usetikzlibrary{fadings,calc,decorations.pathmorphing}
\NewEnviron{ShadeTikZ}[2][]{\begin{tikzfadingfrompicture}[name=temp]%
\begin{scope}[transparent!0,#1] 
\BODY
\end{scope}
\end{tikzfadingfrompicture}%
\tikz[#1]{\begin{scope}[local bounding box=X,opacity=0]%
\BODY
\end{scope}
\path[overlay] (X.center)  node[opacity=0,inner sep=0pt] (img) {\includegraphics{#2}}
  [path fading=temp,fit fading=false,fading transform={shift={(X.center)}}] 
  let \p1=($(X.north east)-(X.south west)+(0.3,0.3)$),
  \p2=($(img.north east)-(img.south west)+(0.3,0.3)$) in
   (X.center)  node[inner sep=0pt,anchor=center]{\pgfmathsetmacro{\myscale}{max(\x1/\x2,\y1/\y2)}%
  \includegraphics[scale=\myscale]{#2}};
 }%
}

\newsavebox\WhatEver
\begin{document}
\begin{ShadeTikZ}[baseline={(txt.base)}]{GoldLeaf.jpg}
\node[draw,thick,align=center,font=\sffamily\bfseries\Large] (txt) 
{2019\\
Hibernation\\[0.5ex]
Awards};
\marmot[yshift=1cm]
\end{ShadeTikZ}
\bigskip
\savebox\WhatEver{\begin{ShadeTikZ}[baseline={(txt.base)}]{GoldLeaf.jpg}
\node[draw,thick,align=center,font=\sffamily\bfseries\Large] (txt) 
{2019\\
Hibernation\\[0.5ex]
Awards};
\marmot[yshift=1cm]
\end{ShadeTikZ}}

\begin{tikzpicture}
 \fill (0,0) rectangle (6,9) node[midway,scale=2]{\usebox\WhatEver};
\end{tikzpicture}
\end{document}

enter image description here