15

I want to fill a tikz-picture with a pattern, based on an external picture. Is this possible? If yes, how?

I tried to define a new pattern with \pgfdeclarepatternformonly, but \pgfuseimage seems to be no valid command inside \pgfdeclarepatternformonly.

Remark:

  • In my example I used a marble-picture, but my question is independend from this special picture.
  • I force the tile to 1cm. Probably it would be better to use the real size of the tile image.
  • If I define \pgfdeclarepatternformonly after \begin{document} the LaTeX error disappear, but the pattern does not work.

My MNWE (minimal not working Example):

\documentclass[]{standalone}
\usepackage{tikz}
\usetikzlibrary{patterns}

%Source: http://upload.wikimedia.org/wikipedia/de/thumb/f/f9/LapG.jpg/83px-LapG.jpg
%But could be any other picture
\pgfdeclareimage[width=1cm,height=1cm]{marble}{83px-LapG}%force quadratic tile

\pgfdeclarepatternformonly{marble}{\pgfpoint{0cm}{0cm}}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{1cm}}{
\pgfuseimage{marble}%! LaTeX Error: Missing \begin{document}.
}

\begin{document}

\begin{tikzpicture}
% This should create a rectangle with 15*15 tiles.
\draw[pattern=marble] (0,0) rectangle (15,15);
\end{tikzpicture} 

\end{document}
4

3 Answers 3

19

It is not possible with pattern, but with the path picture key and a few calculations.

I have used patterns available at texture-s.blogspot.de.


I have turned the code into a small TikZ library which is part of my tikz-ext package.

Its usage can be seen below or in the manual.

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes.geometric, ext.patterns.images}
\pgfsetupimageaspattern[width=1cm]{marble}{marble.jpg}
\pgfsetupimageaspattern[width=2cm]{wall}{concretewall8.jpg}
\pgfsetupimageaspattern[width=2cm]{floor}{pattern4183.jpg}
\begin{document}
\tikz\matrix[column sep=2mm]{
  \path[image as pattern={name=marble}] (0,0) circle[radius=1cm];
& \node[image as pattern={name=wall},star, star point ratio=2, minimum size=2cm] {};
& \path[even odd rule, image as pattern={name=floor}]
  (0,0) circle[radius=1cm] circle[radius=5mm];
& \draw[green, even odd rule, image as pattern={name=floor}]
  (0,0) circle[radius=1cm] circle[radius=5mm];
  \draw[blue, image as pattern={name=floor}]
    (-1cm, -1cm) (0,0) to[bend left] (2,1)
    --++(right:.1) to[bend left] (.1,0) -- cycle;
\\};
\end{document}

Output

enter image description here

8
  • Thanks! That's what I looked for. If possible, I would give you a 2nd +1 for texture-s.blogspot.de.
    – knut
    Apr 6, 2013 at 20:26
  • @knut You are welcome. While the first revision of my answer was merely a proof of concept, I have updated my answer with a small library, where maintaining more than one pattern is easier (the dimensions are calculated automatically). Apr 7, 2013 at 0:34
  • That works great! But by any chance is it possible to apply it on the stroke of a circle? For instance if I do \draw[image as pattern={left}, thick] (0,0) circle[radius=1cm]; then the inside of the node will be painted but the stroke will be black while I’d like no inside and a thick, image-filled, stroke. It would also be great to have it work with a width that fits the content.
    – tobiasBora
    Jun 12 at 13:03
  • 1
    @tobiasBora Using other than a solid line for a path itself is tricky (there are some Q&A around here somewhere). For a simple circle you can just a cutout, i.e. two circles with the even odd rule. For your second problem, either do everything on the same path or make sure that the both paths have the same lower-left bounding box corner, see the fourth example where (-1cm, -1cm) is the lower-left corner of the previous path. Jun 12 at 13:31
  • 1
    @tobiasBora Yes, my answer/this library also only uses a path picture but with two loops to cover the whole area. I didn't really update this in the last 10 years. Jun 12 at 13:56
7

It is possible with PSTricks.

enter image description here

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{graphicx}
\usepackage{pst-fill}
\psboxfill{\includegraphics[scale=0.1]{example-image-A}}
\begin{document}
\begin{pspicture}(4,4)
    \pscircle[fillstyle=boxfill](2,2){2}
    \pscircle(2,2){2}
\end{pspicture}
\end{document}
1
  • 2
    +1 for a possible alternative solution. unfortunately not a TikZ-solution.
    – knut
    Mar 24, 2013 at 10:04
0

For non-repetitive patterns, path picture={\node{whatever thing to draw};} offers a great flexibility, allowing you for instance to draw an image in background at absolute position. Otherwise, you can use the TikZ image fill extensions from the tcolorbox package as proposed here:

enter image description here

\documentclass{article}

\usepackage[skins]{tcolorbox}

\begin{document}

\noindent\begin{tikzpicture}
  \path[fill overzoom image=example-image-a] (0,0) rectangle (\textwidth,4cm);
\end{tikzpicture}

\medskip

\noindent\begin{tikzpicture}
  \path[fill stretch image=example-image-b] (0,0) rectangle (\textwidth,4cm);
\end{tikzpicture}

\medskip

\noindent\begin{tikzpicture}
  \path[fill tile image*={height=3cm}{example-image-c}] (0,0) rectangle (\textwidth,4cm);
\end{tikzpicture}

Absolute positioning:
% absolute coordinates
\noindent\begin{tikzpicture}
  [
    remember picture,
    absolute fill image/.style={
      path picture={
        \node[anchor=center] at (current page.center) {\includegraphics[width=\paperwidth,height=\paperheight]{#1}};
      }
    }
  ]
  \path[draw=green,absolute fill image={example-image-b}] (0,0) circle[radius=1cm];
  \path[draw=red,absolute fill image={example-image-b}] (.5,.5) circle[radius=1cm];
\end{tikzpicture}


\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .