# Rectangle with image as fill pattern with TikZ positioning library

I want to create a custom scale bar for some diagrams in TikZ. I rely heavily on the positioning library to arrange several objects, e.g. the scale bar next to a picture or some labels relative to the scale bar. Now I'd like to use a custom color gradient, for which I created a small PNG and want to fill a rectangle with it. I found a solution how to do than in another TexSE question, but it fails, when the node is positioned relative to another.

What's the problem with my code?

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}
\node [
path picture={
\node at (path picture bounding box.center) {
\includegraphics[height=45mm, width=5mm]{scalebar}};
},
draw,rectangle,
minimum width=5mm, minimum height=45mm,
] (ref) {};
\node [
path picture={
\node at (path picture bounding box.center) {
\includegraphics[height=45mm, width=5mm]{scalebar}};
},
draw,rectangle,
minimum width=5mm, minimum height=45mm,
right= of ref
] (cal) {};
\end{tikzpicture}

\end{document}


Output:

Scale bar PNG:

Edit: I tried Zarko's solution, but with inner sep=0 the boundary becomes to thin to be properly displayed by the PDF viewer unless zoomed in by a large factor. I tested it with the built-in TeXworks viewer and Adobe Reader. The problem is not there if one draws a rectangle with a shading or when using my initial code with path picture. I also tried setting innersep=0.5\pgflinewidth, but the result is the same. Maybe it as something to do with the order in which objects are drawn in the PDF? Is this behavior reproducible for others?

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}[
imagebox/.style = {draw,inner sep=0pt,
minimum width=5mm, minimum height=45mm}
]
\node (ref) [imagebox,rectangle,top color=white,bottom color=black] {};
\node (cal) [imagebox, right= of ref] {\includegraphics[height=45mm, width=5mm]{scalebar}};
\end{tikzpicture}

\end{document}


Output:

• Why don't you just define a custom shading and use that? I'm not sure in which sense you want it to be consistent with the greyscale shading, but a custom shading would work in just the same way. On the other hand, maybe your real use case involves a picture rather than a shading? Obviously in that case, a custom shading isn't an option.
– cfr
Mar 27 '17 at 15:57
• @cfr I want to add scale bars to images. When I use a standard grey scale LUT, the scale bar can be easily constructed solely with tikz command. On the other hand, when custom LUTs (specific to the image processing software used) are used, I want to use PNGs created with the same image software and the same LUT. I guess an ideal way would be to extract the LUT definition from the imaging software and create the bar in TikZ, but this seems quite tedious. Mar 27 '17 at 16:24
• No idea what a LUT is.
– cfr
Mar 27 '17 at 21:16
• @cfr LUT means look up table. Think of it as a custom color palette for pictures. Mar 27 '17 at 21:39

See, if this simplified solution works for you:

   \begin{tikzpicture}[
imagebox/.style = {draw,inner sep=\0.5\pgflinewidth,
minimum width=5mm, minimum height=45mm}
]
\node (ref) [imagebox]  {\includegraphics[height=45mm, width=5mm] {PhhX6}};%{scalebar}} <-- my copy of your png image has name "PhhX6"
\node (cal) [imagebox, right=of ref]
{\includegraphics[height=45mm, width=5mm] {PhhX6}};% {scalebar}};
\end{tikzpicture}


I tested this with option demo for graphicx, which show that this approach works as desired:

Edit (2. try ):

Off-set of the included image, which you observe in your MWE arise because the node in path picture apparently use wrong anchor. If you define for node in path picture as anchor=center, then your solution will work as desired. With this solution the position macro will work as at all other nodes.

For comparison of both described cases, let serve the following MWE. It contain solutions (from left to right):

• simplified solution described at the beginning of this answer (on image designated with "C")
• the case with fill in node (on image designated with "A")
• your solution with correct defined anchors and new node style, which enable simple use this solution (on image designated with "B").

The MWE:

\documentclass{article}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}[node distance=2mm]
\tikzset{
base/.style = {draw, semithick,
minimum height=45mm, minimum width=5mm,
inner sep=0pt},
imagebox/.style = {base,
path picture={\node[anchor=center]
at (path picture bounding box) {#1};},
node contents={}}
}
\node (ref) [base,top color=white,bottom color=black!50, pin=A] {};
\node (cal) [imagebox={\includegraphics[height=45mm,width=5mm]{PhhX6}},% copy of your "scalebar" was renamed to "PhhX6"
right=of ref, pin=B];
\node (xxx) [base,inner sep=0.50\pgflinewidth,left=of ref, pin=C]
{\includegraphics[height=45mm,width=5mm,clip]{PhhX6}};
\end{tikzpicture}


\end{document}

which gives:

• border lines in all cases are equal. This can be seen if enough increase image (I thing that the impression that image "C" has thinner border line is caused by viewer artifacts, but I may be wrong), see image below (it is taken from recent Acrobat Reader DC):

• image "C" is for thickness of border lines bigger (expected)
• the benefits of the first proposed solution is simplicity, however, with new defined node style imagebox, which preserve correct positioning of node as well as image included as path image, the use of the second solution is almost the same handy
• I tried something like this before, but had problems with the rectangular outline not being proberly displayed in the PDF. I edited my question with some code to illustrate. Mar 23 '17 at 15:27
• See, if new example is more close to your wish. You can experimenting with other border line width. Image is taken from Sumatra viewer. Mar 23 '17 at 15:50
• It comes close but still the outline vanishes at some zoom levels. Additionaly, I'd like to have a consistent look with the grey level scale bar I generated with top color and bottom color (see edited question). I found a solution which looks good for me. I posted it as a separate answer. I'm not sure if I should accept my own answer, but it works best for me, so far. Mar 23 '17 at 16:26
• Thanks for the update. Your comparison shows that the first two bars look consistent and the third bar's left edge looks to thin. So I'll accept my own answer for now. Though, ideally someone could explain the odd behavior of path picture in combination with right=of. Thanks, Zarko, for the continuous struggle towards a better solution! Mar 24 '17 at 9:30
• @CorneliusSicker, meanwhile I reinspected my answer, your solution and also claim, that the node's borders thickness are different (around that we disagree :-) ). Anyway, beside first solution I also add solution for your problem, which work correctly in any circumstances and for it define new node style. Mar 25 '17 at 12:52

By trial and error I found out that the anchor of the node needs to be center for path picture to work properly. Since right=of sets anchor=west things get messed up. A working solution is thus to add anchor=center and adjust the distance accordingly, e.g. by half of the object's width.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}
\node (ref) [draw,rectangle,inner sep=0,minimum width=5mm,minimum height=45mm,top color=white,bottom color=black] {};
\node [
path picture={
\node at (path picture bounding box.center) {
\includegraphics[height=45mm, width=5mm]{scalebar}};
},
draw,rectangle,
minimum width=5mm, minimum height=45mm,
right=of ref,
anchor=center
] (cal) {};
\end{tikzpicture}

\end{document}