在下面的 MWE 中,当前产生以下输出(单击可获得全分辨率):
... 我想要:
- 将四幅图像排列成两行两列,为此我使用了一个
\matrix
节点\tikz
, - 让它们在页面上全部旋转,包括标题,
- 缩放这些图像,使它们填满剩余的页面空间(或适合它们各自的容器节点) - 同时保持纵横比,并
row sep
尊重column sep
\matrix
- 使用 tikz 命令对它们进行注释
\draw
(原则上,我会在图像的圆圈周围添加红色矩形边框,但这里为了简单起见,它们只是为了居中)。
当前示例中存在以下问题:
\node
do中的 s根据\matrix
页面高度缩放(因为它们会随着宽度旋转) - 但旋转后的节点高度超出了页面宽度- 对于我来说,获取注释矩形坐标的最简单方法是使用
tikzedt
,将图像宽度设置为 10cm;最后使用生成的数字(例如\draw[rd] (1.1,1.1) node (f1) {} rectangle (-1.1,-1.1);
)作为最终图像宽度(例如\draw[rd] (1.1\imw,1.1\imw) node (f1) {} rectangle (-1.1\imw,-1.1\imw);
)的缩放因子。问题是,这里我不知道最终图像宽度是多少,因为图像应该缩放
此外,在 MWE 中,标题也会超出页边距 - 但在这种情况下,考虑到页边距的宽度,这实际上可能没问题。所以我想知道如何在两种情况下实现这一点:标题都适合页面边界内;标题位于页面边界之外,只有节点/图像矩阵适合内部。
那么,什么是最简单的方法,实现图像缩放,保持纵横比,将其放入一个节点矩阵中,该节点矩阵缩放到(适合)页边距内的页面大小 - 标题位于页边距边界内和页边距边界外;并获取它们的最终尺寸,以便将它们用于注释图形的坐标?
编辑:刚刚发现我混淆了下面 MWE 中图像的宽度和高度;因此,如果在下面的 MWE 中替换所有max size={0.5\textwidth}{0.5\textheight}
带有的实例,我会得到更预期的输出:max size={0.5\textheight}{0.5\textwidth}
图像的比例大小现在看起来没问题(但请注意,由于 img1 小于节点边界,因此不会放大 - 但在这种情况下这不是问题) - 但整体上,定位仍然偏离页边距边界(并且似乎与标题有点相关);所以其余问题仍然存在......
MWE 代码:
\documentclass[10pt,twoside,openright]{book}
% to generate images, run the first time with:
% pdflatex -shell-escape test.tex
% (ImageMagick `convert` commands tested in `bash` shell)
\immediate\write18{
convert -size 200x100 gradient:\#4b4-\#bfb -fill gradient:green-yellow -draw 'circle 50,30 50,50' img1.png ;
convert -size 100x200 gradient:\#44b-\#bbf -fill gradient:green-yellow -draw 'circle 70,130 70,150' img2.png ;
convert -size 300x200 gradient:\#b44-\#fbb -fill gradient:blue-yellow -draw 'circle 250,30 250,50' img3.png ;
convert -size 200x300 gradient:\#4bb-\#ffb -fill gradient:blue-yellow -draw 'circle 70,230 70,250' img4.png ;
}
\usepackage{tikz}
\usepackage[export]{adjustbox}
\pagecolor{yellow!10} % \usepackage{xcolor}
\usepackage{lua-visual-debug} % compile with lualatex test.tex, for visual indication of margins
% both of these use adjustbox:
% http://tex.stackexchange.com/questions/32886/how-to-fit-a-large-figure-to-page
% http://tex.stackexchange.com/questions/44427/rotate-picture-with-caption
% note: \draw tikz dimensions: in unit centimeter
\begin{document}
\begin{figure}[p]
\begin{adjustbox}{addcode={\begin{minipage}{\width}}{\caption{%
Here is a caption of the figure which is so long that
it has to be wrapped over multiple lines, but should
not exceed the width (height after the rotation) of the image.
}\end{minipage}},rotate=90,center}
%
%\includegraphics[scale=.6]{test/picture.png}%
%
\begin{tikzpicture}[
ns/.style={inner sep=0pt,outer sep=0pt},
mw/.style={minimum width=0.5\textheight, minimum height=0.5\textwidth},
rd/.style={draw=red,line width=2pt},
]
\matrix[ns,row sep=1mm,column sep=1mm] {
% row 1, col 1:
\node[ns,mw,draw] {%
\includegraphics[max size={0.5\textwidth}{0.5\textheight},keepaspectratio]{img1.png}%
};%
\draw[rd] (1.1,1.1) node (f1) {} rectangle (-1.1,-1.1);%
&% %end column%
% row 1, col 2:
\node[ns,mw,draw] {
\includegraphics[max size={0.5\textwidth}{0.5\textheight},keepaspectratio]{img2.png}%
};%
\draw[rd] (1.1,1.1) node (f2) {} rectangle (-1.1,-1.1);%
\\% %end row%
% row 2, col 1:
\node[ns,mw,draw] {
\includegraphics[max size={0.5\textwidth}{0.5\textheight},keepaspectratio]{img3.png}%
};%
\draw[rd] (1.1,1.1) node (f3) {} rectangle (-1.1,-1.1);%
&% %end column%
% row 2, col 2:
\node[ns,mw,draw] {
\includegraphics[max size={0.5\textwidth}{0.5\textheight},keepaspectratio]{img4.png}%
};%
\draw[rd] (1.1,1.1) node (f4) {} rectangle (-1.1,-1.1);%
\\% %end row%
};
\end{tikzpicture}
%
\end{adjustbox}
\end{figure}
\end{document}
答案1
好的,我想我明白了;下面的 MWE 结果是这样的(单击可查看高分辨率):
...并且框和图像适合页面的空间,并且标题在里面(ATM,我甚至无法想象将标题放在外面、在页边距上需要什么:)
)。
简而言之,这个技巧如下:
- 首先,根据在排版之前测量/获取标题的大小?,为了在图像排版之前获取标题的大小,我们应该在 中排版标题
\savebox
,在 内{figure}
,但在主程序{adjustbox}
开始 之前- 此时,一旦我们有了排版标题框大小,我们也可以对各个节点的宽度/高度进行相关计算
本质上,这就是图像/标题像答案一样排版所需要的全部内容;但对于注释的相对图像大小引用来说,这还不够。
首先,我认为fitting node
风格(例如在单个 PDF 页面上剪辑多个 PDF 图像并按彼此的尺寸缩放?;另见下面的代码)可以使用,但这总是与崩溃! Dimension too large.
,这在我意识到这些节点中的任何地方,\pgf@pathmaxx
和这样的总是+/- 16000pt后就说得通了。然后我在tikz
手册中注意到有一个\pgf@picmaxx
和相关的,它们确实提供了更合理的估计——但只有在放置节点之后(所以它们不能真正用于设置节点大小fitting node
)。而且,那些更合理的估计似乎也不依赖于图像的最终大小。但是:
- 值得庆幸的是,事实证明它
\adjustbox
可以保存包含图像的最终尺寸,使用如下键gstore width=\adjw
因此,基本上,而不是\node{ \includegraphics[max size={...
,人们必须使用\node{ \begin{adjustbox}{max size={...,gstore width={... \includegraphics...
(甚至不确定是否需要外部包装\node
- 是的,因为外部\matrix
);然后根据gstore width
节省的长度添加带注释的绘制等(和不是就外部包裹节点的大小而言)。
作为测试,这些红色/紫色方块都应该使用相对参考来内接一个矩形,其尺寸为缩放后图像最终尺寸的一半0.25\adjw
- 看起来,它有效。然而,我希望有一种更简单的方法来做到这一点......
无论如何,这里是 MWE 代码(抱歉有点混乱):
\documentclass[10pt,twoside,openright]{book}
% to generate images, run the first time with:
% pdflatex -shell-escape test.tex
% (ImageMagick `convert` commands tested in `bash` shell)
\immediate\write18{
convert -size 200x100 gradient:\#4b4-\#bfb -fill gradient:green-yellow -draw 'circle 50,30 50,50' img1.png ;
convert -size 100x200 gradient:\#44b-\#bbf -fill gradient:green-yellow -draw 'circle 70,130 70,150' img2.png ;
convert -size 300x200 gradient:\#b44-\#fbb -fill gradient:blue-yellow -draw 'circle 250,30 250,50' img3.png ;
convert -size 200x300 gradient:\#4bb-\#ffb -fill gradient:blue-yellow -draw 'circle 70,230 70,250' img4.png ;
}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{fit}
\usepackage[export]{adjustbox}
\pagecolor{yellow!10} % \usepackage{xcolor}
\usepackage{lua-visual-debug} % compile with lualatex test.tex, for visual indication of margins
\usepackage{trace}
% both of these use adjustbox:
% https://tex.stackexchange.com/questions/32886/how-to-fit-a-large-figure-to-page
% https://tex.stackexchange.com/questions/44427/rotate-picture-with-caption
% note: \draw tikz dimensions: in unit centimeter
\makeatletter
\tikzset{ %https://tex.stackexchange.com/questions/47704
fitting node/.style={
inner sep=0pt,
fill=none,
draw=none,
%reset transform,
fit={(\pgf@pathminx,\pgf@pathminy) (\pgf@pathmaxx,\pgf@pathmaxy)},
},
picfitting node/.style={ % also this: ! Dimension too large.
inner sep=0pt,
fill=none,
draw=none,
%reset transform,
fit={(\pgf@picminx,\pgf@picminy)(\pgf@picmaxx,\pgf@picmaxy)},
},
reset transform/.code={\pgftransformreset},
tt/.code={\pgf@relevantforpicturesizetrue \typeout{tt \the\pgf@pathminx,\the\pgf@pathminy,\the\pgf@pathmaxx,\the\pgf@pathmaxy; \the\pgf@picminx,\the\pgf@picminy,\the\pgf@picmaxx,\the\pgf@picmaxy; }},
}
\makeatother
\begin{document}
\begin{figure}[p]
% https://tex.stackexchange.com/questions/227145/measuring-getting-size-of-caption-before-it-is-typeset
\newsavebox{\boxcapt}% is allocated (though not set) globally now, https://tex.stackexchange.com/questions/7134/making-register-declarations-local-undef
\savebox{\boxcapt}{%
\parbox{\textheight}{% \width here is undefined (\adjustbox is below)
\caption{%
Here is a caption of the figure which is so long that
it has to be wrapped over multiple lines, but should
not exceed the width (height after the rotation) of the image.
}%
}% %end \parbox%
}% %end \savebox%
% prep calcs
\newlength{\grsep}\setlength{\grsep}{1mm}%
\newlength{\gcsep}\setlength{\gcsep}{1mm}%
\newlength{\gnw}\newlength{\gnh}% node w, h (when rotated)
\setlength{\skip0}{\dimexpr\ht\boxcapt+\dp\boxcapt}%
% -1pt here just to avoid complaints: LaTeX Warning: Float too large for page by 0.79996pt on input line 153.
\pgfmathsetlength{\gnw}{0.5*(\textheight-\gcsep-8*\pgflinewidth)-1pt}%
\pgfmathsetlength{\gnh}{0.5*(\textwidth-\grsep-\the\skip0-8*\pgflinewidth)-1pt}%
\global\grsep=\grsep\global\gcsep=\gcsep%
\global\gnw=\gnw\global\gnh=\gnh%
\newlength{\adjw}\newlength{\adjh}
%
\begin{adjustbox}{%
precode={\begin{minipage}{\width}},
appcode={% addcode= code after:
%\typeout{boxcapt out: wd is: \the\wd\boxcapt, ht is: \the\ht\boxcapt, dp is: \the\dp\boxcapt ; skip1: \the\skip1; skip3: \the\skip3; glw,h: \the\globimw, \the\globimh; tw \the\textwidth}% all are here
\break% same w/ \linebreak, \\ or \newline
\usebox{\boxcapt}% place the caption, finally
\end{minipage}%
},
rotate=90,center%
}% %closing of \begin{adjustbox}%
%
\begin{tikzpicture}[
remember picture,
ns/.style={inner sep=0pt,outer sep=0pt},
mw/.style={minimum width=\gnw, minimum height=\gnh},
rd/.style={draw=red,line width=1pt},
rdb/.style={draw=red!60!blue,line width=2pt},
%tt/.code={\makeatletter\typeout{tt \the\pgf@pathminx,\the\pgf@pathminy,\the\pgf@pathmaxx,\the\pgf@pathmaxy}\makeatother}, % have to wrap w makeatletter outside
]
\matrix[ns,row sep=\grsep,column sep=\gcsep] {
% row 1, col 1:
\node[ns,mw,draw,tt] (n1) {%
\tikz\node[ns,remember picture, overlay, tt] (n1a) {% fitting node: ! Dimension too large.
\begin{adjustbox}{max size={\gnw}{\gnh},gstore width=\adjw,gstore totalheight=\adjh}%
\includegraphics{img1.png}%
\end{adjustbox}%
};%
%\typeout{\meaning\width,\meaning\height}% undefined by now
% tt otputs always +- 16000; but this:
\makeatletter\typeout{\the\adjw, \the\adjh -- \the\pgf@pathminx,\the\pgf@pathminy,\the\pgf@pathmaxx,\the\pgf@pathmaxy; \the\pgf@picminx,\the\pgf@picminy,\the\pgf@picmaxx,\the\pgf@picmaxy;}\makeatother%
% outputs: 16000.0pt,16000.0pt,-16000.0pt,-16000.0pt; -136.48868pt,-77.37756pt,136.48868pt,77.37756pt
};%
% also here: -136.48868pt,-77.37756pt,136.48868pt, 77.37756pt;
\makeatletter\typeout{\the\adjw, \the\adjh -- \the\pgf@pathminx,\the\pgf@pathminy,\the\pgf@pathmaxx,\the\pgf@pathmaxy; \the\pgf@picminx,\the\pgf@picminy,\the\pgf@picmaxx,\the\pgf@picmaxy;}\makeatother%
\path let \p1=(n1a.north east), \p2=(n1a.south west), \p3=($(\p1)-(\p2)$) in node{\typeout{\x3, \y3}};%
\draw[rd] (1.1,1.1) node (f1) {} rectangle (-1.1,-1.1);%
\draw[rdb] (0.25\adjw,0.25\adjh) node (f1a) {} rectangle (-0.25\adjw,-0.25\adjh);%
&% %end column%
% row 1, col 2:
\node[ns,mw,draw,tt] (n2) {
\begin{adjustbox}{max size={\gnw}{\gnh},gstore width=\adjw,gstore totalheight=\adjh}%
\includegraphics{img2.png}%
\end{adjustbox}%
};%
\makeatletter\typeout{\the\pgf@pathminx,\the\pgf@pathminy,\the\pgf@pathmaxx,\the\pgf@pathmaxy; \the\pgf@picminx,\the\pgf@picminy,\the\pgf@picmaxx,\the\pgf@picmaxy;}\makeatother%
\path let \p1=(n2.north east), \p2=(n2.south west), \p3=($(\p1)-(\p2)$) in node{\typeout{\x3, \y3}};%
\draw[rd] (1.1,1.1) node (f2) {} rectangle (-1.1,-1.1);%
\draw[rdb] (0.25\adjw,0.25\adjh) node (f1a) {} rectangle (-0.25\adjw,-0.25\adjh);%
\\% %end row%
% row 2, col 1:
\node[ns,mw,draw] (n3) {
\begin{adjustbox}{max size={\gnw}{\gnh},gstore width=\adjw,gstore totalheight=\adjh}%
\includegraphics{img3.png}%
\end{adjustbox}%
};%
\path let \p1=(n3.north east), \p2=(n3.south west), \p3=($(\p1)-(\p2)$) in node{\typeout{\x3, \y3}};%
\draw[rd] (1.1,1.1) node (f3) {} rectangle (-1.1,-1.1);%
\draw[rdb] (0.25\adjw,0.25\adjh) node (f1a) {} rectangle (-0.25\adjw,-0.25\adjh);%
&% %end column%
% row 2, col 2:
\node[ns,mw,draw] (n4) {
\begin{adjustbox}{max size={\gnw}{\gnh},gstore width=\adjw,gstore totalheight=\adjh}%
\includegraphics[max size={\gnw}{\gnh},keepaspectratio]{img4.png}%
\end{adjustbox}%
%\typeout{\the\wd\collectedbox,\the\ht\collectedbox,\the\dp\collectedbox}% 0 by now
};%
\path let \p1=(n4.north east), \p2=(n4.south west), \p3=($(\p1)-(\p2)$) in node{\typeout{\x3, \y3}};%
\draw[rd] (1.1,1.1) node (f4) {} rectangle (-1.1,-1.1);%
\draw[rdb] (0.25\adjw,0.25\adjh) node (f1a) {} rectangle (-0.25\adjw,-0.25\adjh);%
\\% %end row%
};
\end{tikzpicture}
%
\end{adjustbox}
\end{figure}
\end{document}