在 tikz 节点的旋转矩阵中缩放(和注释)图像,缩放到页面大小?

在 tikz 节点的旋转矩阵中缩放(和注释)图像,缩放到页面大小?

在下面的 MWE 中,当前产生以下输出(单击可获得全分辨率):

测试.png

... 我想要:

  • 将四幅图像排列成两行两列,为此我使用了一个\matrix节点\tikz
  • 让它们在页面上全部旋转,包括标题,
  • 缩放这些图像,使它们填满剩余的页面空间(或适合它们各自的容器节点) - 同时保持纵横比,并row sep尊重column sep\matrix
  • 使用 tikz 命令对它们进行注释\draw(原则上,我会在图像的圆圈周围添加红色矩形边框,但这里为了简单起见,它们只是为了居中)。

当前示例中存在以下问题:

  • \nodedo中的 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}

测试2.png

图像的比例大小现在看起来没问题(但请注意,由于 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 结果是这样的(单击可查看高分辨率):

测试.png

...并且框和图像适合页面的空间,并且标题在里面(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}

相关内容