我正在尝试构建一个 tikz 矩阵,其中每个单元格要么是空的,要么包含图像或图像的一部分。也就是说,如果单个图像很大,则可能跨越多个单元格。
我正在使用以下内容测试图像kings
使用以下代码从 OpenClipart调用:
\documentclass[tikz]{standalone}
\usetikzlibrary{fit, matrix}
\begin{document}
\begin{tikzpicture}
\matrix [
matrix of nodes,
row sep=-\pgflinewidth,
column sep=-\pgflinewidth,
nodes={
rectangle, draw=black, minimum height=11mm, minimum width=11mm,
anchor=center, inner sep=0pt, outer sep=0pt, font=\Huge
},
nodes in empty cells,
name=table
] {
& & & & \\
& & & & \\
& & & & \\
& & & & \\
};
% Using draw just to make the problem clear
\node[fit=(table-2-3)(table-2-4), draw]{
% This works, but is there a more robust way?
%\vspace{-0.1cm}
\includegraphics[width=22mm, height=11mm]{kings}
};
\node[fit=(table-3-1)(table-4-2), draw]{
%\vspace{-0.1cm}
\includegraphics[width=22mm, height=11mm]{kings}
};
\end{tikzpicture}
\end{document}
这将产生以下输出:
在这里,我使用draw
只是为了让问题更清楚:似乎图像的下半部分用于居中。通过使用负片,vspace
我可以让它看起来不错,但它看起来不太好或不稳固。有没有更好的方法?
还有一个问题,我希望图像内部的网格线消失(即,图像应该绘制在网格的内线上),但外线应该保持完整。同样,我可以通过执行类似 的操作“几乎”做到这一点draw=white
,但会产生类似效果(图像上方的黑线会断开,因为在图像周围绘制了一个白色矩形):
答案这里帮助我更接近目标,但只考虑单个节点内的单个图像。
答案1
该库的手册说明fit
:
fit 选项的具体效果如下:
- […]
- […]
- […]
- […]
- […]
- 节点排版后,其高度和深度将被调整,使得它们加起来等于计算出的边界框的高度,并且节点的文本在框内垂直居中。
上面的意思是,一般来说,如果节点包含文本(如上例中的框),它将位于框内的中央。将文本放在其他地方会很困难,特别是更改节点的锚点不会产生预期的效果。相反,您应该做的是创建一个带有 fit 选项的不包含任何文本的节点,为其命名,然后使用普通节点在所需位置添加文本。或者,考虑使用标签或 pin 选项。
这意味着创建的节点将具有text height=5.5mm
和text depth=5.5mm
。您的图片只有高度,没有深度,这会将其向上推。
最简单的解决方案是遵循手册的建议。
我们将使用没有文本的拟合节点,并使用label
键将另一个节点放置在拟合节点的中心。
fill
只需将节点(而不是标签)与背景颜色(此处)结合,即可删除图片后面的线条white
。如果您有更复杂的图形,这可能会失败。(我认为这是一种肮脏的解决方案,但有时它们是最简单的。)
这inner sep=-.5\pgflinewidth
使得拟合节点的线宽实际上比其拟合节点的线宽小一半,这样您就不会过度绘制未穿过图片的线条。如果您对矩阵节点使用不同的线宽,则需要调整这一点,但它可以自动完成,这样您就不必因为想尝试另一种线宽而调整一堆样式。
由于标签和矩阵本身都是节点,因此我也会inner sep=0pt
向它们添加节点,以便它们不会对图片的边界框产生贡献。
我使用这种kings
风格使其易于使用,而不必重复大量相同的 TikZ 指令。
根据您的实际图形,可能会在这里或那里进行调整。
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{fit, matrix}
\begin{document}
\begin{tikzpicture}[
kings/.style={
fit={#1},
fill=white, % overdraw lines behind the picture
inner sep=-.5\pgflinewidth, % but don't touch the lines around it
node contents=, % no text in the fitted node → no need for {}
label={
[inner sep=0pt] % the label is a node, we don't want that padding here either
center: % the label will be placed at the center of the fitted node
{\includegraphics[width=22mm, height=11mm]{kings}}}}]
\matrix [
matrix of nodes,
inner sep=0pt, % no padding around the cells
row sep=-\pgflinewidth,
column sep=-\pgflinewidth,
nodes={
rectangle, draw=black, minimum height=11mm, minimum width=11mm,
anchor=center, inner sep=0pt, outer sep=0pt
},
nodes in empty cells,
name=table
] {
& & & & \\
& & & & \\
& & & & \\
& & & & \\
};
\node[kings=(table-2-3)(table-2-4)];
\node[kings=(table-3-1)(table-4-2)];
\end{tikzpicture}
\end{document}