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}
3
  • Inside a PGF picture, you will need to put \pgfuseimage inside a \pgftext. Though, this will still not show the image. Mar 23, 2013 at 23:04
  • I think I found a similar problem with text as pattern. The corresponding question at sourceforge is unanswered.
    – knut
    Mar 24, 2013 at 14:08
  • I found another (French) discussion in the net for this question. Result: It is not possible.
    – knut
    Mar 24, 2013 at 14:25

2 Answers 2

18

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 and added a macro and two keys:

  • \pgfSetupImageAsPattern[<opt arguments for \pgfdeclareimage>]{<name>}{<path/file>}
    is a wrapper for \pgfdeclareimage but also automatically measures the resulting image (if only one of the dimensions (width and height) is given, PGF keeps the aspect ratio of the image, but it is not accessible for the user).

  • use image as pattern=<name>
    sets up the pattern <name> for use with the key image as pattern. This key is intended to set the image scope-wide. It can also be used at every path, though it may be preferable to setup an own style:

    \tikzset{marble/.style={use image as pattern=marble, image as pattern}}
    

    and then simply use \path[marble] …;.

  • image as pattern=<opt arguments for \pgftext>
    actually uses the previously set <name> pattern. The key accepts one optional argument that is forwarded to the internally used \pgftext.

The placing of these images starts with one image centered on the south west point of the path. This can be changes by the optional argument to image as pattern as shown in the two latter examples of the document below.
As this is hardly noticeable with white-noise-ish marble patterns I have used the following image to show this:

enter image description here

Keys useable for \pgftext are

  • center (default), left, right, top, bottom, base (=bottom as PGF images do not have a depth),
  • x, y (similar to xshift and yshift), and
  • rotate (needs manual adjusting with patterns.image).

Code

Library tikzlibrarypatterns.image.code.tex

% This is the TikZ library patterns.images
% Load with \usetikzlibrary{patterns.images}
%
% Macro:
%  - \pgfSetupImageAsPattern[<opt arguments for \pgfdeclareimage>]{<name>}{<path/file>}
%
% Keys are:
%  - use image as pattern=<name>
%  - image as pattern=<opt arguments for \pgftext>

\newlength\qrr@pgf@iap@width
\newlength\qrr@pgf@iap@height

\def\pgfSetupImageAsPattern{\pgfutil@ifnextchar[\qrr@pgfSetupImageAsPattern{\qrr@pgfSetupImageAsPattern[]}}
\def\qrr@pgfSetupImageAsPattern[#1]#2#3{% #1 = options
                                        % #2 = image name
                                        % #3 = file name
  \pgfdeclareimage[#1]{qrr@pgf@iap@#2}{#3}%
  \sbox\pgfutil@tempboxa{\pgfuseimage{qrr@pgf@iap@#2}}%
  \expandafter\edef\csname qrr@pgf@iap@#2@width\endcsname{\the\wd\pgfutil@tempboxa}%
  \expandafter\edef\csname qrr@pgf@iap@#2@height\endcsname{\the\ht\pgfutil@tempboxa}%
}
\tikzset{
  image as pattern/.code={
    \edef\qrr@pgf@iap@options{#1}%
    \pgfkeysalso{/tikz/path picture={%
      \pgf@process{\pgfpointanchor{path picture bounding box}{north east}}%
      \pgf@xa\pgf@x\pgf@ya\pgf@y
      \pgf@process{\pgfpointanchor{path picture bounding box}{south west}}%
      \pgf@xb\pgf@x\pgf@yb\pgf@y\pgf@yc\pgf@yb
      \pgfutil@loop
        {%
        \pgfutil@loop
          \expandafter\pgftext\expandafter[\qrr@pgf@iap@options,at=\pgfqpoint{\pgf@xb}{\pgf@yb}]{\pgfuseimage{qrr@pgf@iap@\qrr@pgf@iap@name}}%
          \ifdim\pgf@yb<\pgf@ya
          \advance\pgf@yb\qrr@pgf@iap@height
        \pgfutil@repeat
        }%
        \ifdim\pgf@xb<\pgf@xa
        \advance\pgf@xb\qrr@pgf@iap@width
        \pgf@yb\pgf@yc
      \pgfutil@repeat
    }}%
  },
  use image as pattern/.code={%
    \edef\qrr@pgf@iap@name{#1}%
    \expandafter\qrr@pgf@iap@width\csname qrr@pgf@iap@#1@width\endcsname
    \expandafter\qrr@pgf@iap@height\csname qrr@pgf@iap@#1@height\endcsname
  }
}
\endinput

Test file

\documentclass[tikz,convert]{standalone}
\usetikzlibrary{shapes.geometric, patterns.images}
\pgfSetupImageAsPattern[width=1cm]{marble}{pattern1_.jpg}
\pgfSetupImageAsPattern[width=2cm]{leopard}{texture_4_.png}
\pgfSetupImageAsPattern[width=2cm]{cross}{cross}
\begin{document}
\begin{tikzpicture}[use image as pattern=marble]
\path[image as pattern] (0,0) circle (1cm);
\end{tikzpicture}
\begin{tikzpicture}[use image as pattern=leopard]
\node[image as pattern,star, star point ratio=2,minimum size=2cm] {};
\end{tikzpicture}

\begin{tikzpicture}[use image as pattern=cross]
\draw[image as pattern] (0,0) rectangle (5,5);
\end{tikzpicture}
\begin{tikzpicture}[use image as pattern=cross]
\draw[image as pattern={left,bottom}] (0,0) rectangle (5,5);
\end{tikzpicture}
\end{document}

Output 1

enter image description here enter image description here

Output 2

enter image description hereenter image description here

5
  • 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
  • @Qrrbrbirlbel I tried to use a pdf, or ps, or eps image, all give me a black filling. Does your library compatible with vectorial images ?
    – Tarass
    Jun 16, 2014 at 8:44
  • @Tarass Hm, seems fishy. The cross file I have used in my example was certainly a PDF. Are you compiling with pdfLaTeX? Apr 19, 2015 at 0:38
  • Thank you for your concern, but I don't remember why I asked that, and I don't need it now.
    – Tarass
    Apr 19, 2015 at 12:40
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

You must log in to answer this question.

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