如何为大图像的各部分创建放大的子图和相应的框

如何为大图像的各部分创建放大的子图和相应的框

更新如下

我希望标题能说明我想做什么。我有一张大图像,用于图像处理主题的论文,我想显示这张大图像,并放大框(通常具有相同的纵横比)。我还想在大图像上叠加彩色框以显示我正在放大的部分。以下是一个例子:

在此处输入图片描述

我目前通过获取大图像并将所需的缩放区域复制到单独的图像中,并创建叠加框架来实现这一点,所有这些都在 MATLAB 中完成。然后我使用本文中讨论的技术上一个问题我将所有图像很好地对齐。

我的新问题是,是否可以完全在 LaTeX 中创建类似的最终产品,以便我需要的唯一外部文件是原始大图像,并且一些 LaTeX 组件(我正在考虑 Tikz,但接受建议)创建叠加的框架和裁剪/缩放的副本,然后按照我的示例所示排列它们,或者使用该技术这里使它们整齐地对齐。

另外,我展示的例子只是一个示例布局;理想情况下,任何解决方案都应该足够灵活,以允许重新排列成其他合理的排列,比如在顶部放置大图像(全线宽),在其下方的水平线上放置两个或三个缩放框。

谢谢。

我正在处理的图像在这里:

美术馆

更新

请参阅下面 Jake 的回复,了解当前最佳/完整版本的代码。唯一未解决的问题就是,虽然子标题可以工作,并且可以引用\subref{},但间谍库会多次处理标签,从而导致出现关于多次定义标签的警告。

因此,我暂时选择不使用子标题/标签,因为颜色编码可以清楚地显示放大图像和大图像之间的关系。可以通过替换以下行来删除子标题

\newcommand\phantomimage{\subcaptionbox{\label{\pgfkeysvalueof{/tikz/subfigurename}}}{\phantom{\rule{\imagewidth}{\imageheight}}}}

\newcommand\phantomimage{\phantom{\rule{\imagewidth}{\imageheight}}}

我又提出了一个问题这里关于标签多重定义的spy问题。如果有新问题的解决方案,我会再次更新这篇文章。

最后更新

子标题问题已解决。请参阅下面 Jake 的回复以了解最终代码和用法。

答案1

这是使用spyMartin 提到的库的一个例子。我编写了几种样式,可用于创建放大数组,具有任意数量的行和列,放置在原始图像的任意一侧,具有可指定的间隙。放大将占用与原始图像相同的空间。

图像本身和放大倍数是subcaptionboxes,这需要包。它们被分配了和subcaption形式的标签,可以使用和进行引用。如果没有为 提供选项,则将假定默认名称为。<figurename>-image<figurename>-zoom\ref\subreffigurenametikzpicturezoombox

放大的中心点以相对坐标指定: \zoombox{0,0}将放大在左下角,\zoombox{1,1}在右上角。

您可以使用可选参数指定各个缩放框的缩放系数:\zoombox[magnification=5]{0.5,0.5}将放大图像中间,放大 5 倍。

可以使用可选参数绘制带有彩色框架的框和放大图[color code=<color>]

help grid要在原始图像上显示网格以帮助放置缩放点,请使用图像节点中的选项。

可以使用选项 来代替使用颜色,使用黑白虚线图案black and white。这将覆盖color code选项。要自动为每个框使用不同的虚线图案,请使用black and white=cycle

更新修复了黑白图案无法正确初始化的问题。谢谢,SSilk。

你会使用

\begin{figure}\centering
\begin{tikzpicture}[zoomboxarray]
    \node [image node] { \includegraphics[width=0.45\textwidth]{gallery} };
    \zoombox{0.175,0.9}
    \zoombox[magnification=2]{0.7,0.6}
    \zoombox{0.15,0.3}
    \zoombox[magnification=10]{0.86,0.35}
\end{tikzpicture}
\caption{The National Gallery of Canada}
\end{figure}

相同示例,但有彩色轮廓

\begin{tikzpicture}[zoomboxarray]
    \node [image node] { \includegraphics[width=0.45\textwidth]{gallery} };
    \zoombox[color code=red]{0.175,0.9}
    \zoombox[magnification=2,color code=yellow]{0.7,0.6}
    \zoombox[color code=orange]{0.15,0.3}
    \zoombox[magnification=10,color code=lime]{0.86,0.35}
\end{tikzpicture}

在原始图像上显示网格:

\begin{tikzpicture}[zoomboxarray]
    \node [image node,help grid] { \includegraphics[width=0.45\textwidth]{gallery} };
    \zoombox[color code=red]{0.175,0.9}
    \zoombox[magnification=2,color code=yellow]{0.7,0.6}
    \zoombox[color code=orange]{0.15,0.3}
    \zoombox[magnification=10,color code=lime]{0.86,0.35}
\end{tikzpicture}

要在原始图像下方的水平行中获得三个放大倍数,如下所示

你会使用

\begin{figure}[ht]\centering
\begin{tikzpicture}[zoomboxarray, zoomboxes below, zoomboxarray inner gap=0.5cm, zoomboxarray columns=3, zoomboxarray rows=1]
    \node [image node] { \includegraphics[width=0.45\textwidth]{gallery} };
    \zoombox[magnification=2]{0.175,0.72}
    \zoombox[magnification=2]{0.71,0.5}
    \zoombox[magnification=10]{0.86,0.38}
\end{tikzpicture}
\caption{The National Gallery of Canada}
\end{figure}

使用connect zoomboxes绘制连接线将缩放框链接到图像中的点,并使用样式更改线条颜色和粗细zoombox paths

\begin{tikzpicture}[zoomboxarray,
    zoomboxes below,
    zoomboxarray columns=3,
    zoomboxarray rows=1,
    connect zoomboxes,
    zoombox paths/.append style={ultra thick, red}]
    \node [image node] { \includegraphics[width=0.45\textwidth]{gallery} };
    \zoombox[magnification=2]{0.175,0.72}
    \zoombox[magnification=2]{0.71,0.5}
    \zoombox[magnification=10]{0.86,0.38}
\end{tikzpicture}

使用black and white黑白虚线绘制方框:

\begin{tikzpicture}[
    zoomboxarray,
    black and white
]
    \node [image node] { \includegraphics[width=0.45\textwidth]{gallery} };
    \zoombox{0.27,0.9}
    \zoombox[color code=red,magnification=6]{0.4,0.83}
    \zoombox{0.42,0.45}
    \zoombox[magnification=5]{0.95,0.52}
\end{tikzpicture}

使用black and white=cycle不同的黑白虚线图案绘制每个框:

\begin{tikzpicture}[
    zoomboxarray,
    black and white=cycle
]
    \node [image node] { \includegraphics[width=0.45\textwidth]{gallery} };
    \zoombox{0.27,0.9}
    \zoombox[color code=red,magnification=6]{0.4,0.83}
    \zoombox{0.42,0.45}
    \zoombox[magnification=5]{0.95,0.52}
\end{tikzpicture}

完整代码如下:

\documentclass{article}
\usepackage{graphicx}
\usepackage{caption}
\usepackage{subcaption}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{spy,calc}
\usepackage{hyperref}


\newif\ifblackandwhitecycle
\gdef\patternnumber{0}

\pgfkeys{/tikz/.cd,
    zoombox paths/.style={
        draw=orange,
        very thick
    },
    black and white/.is choice,
    black and white/.default=static,
    black and white/static/.style={ 
        draw=white,   
        zoombox paths/.append style={
            draw=white,
            postaction={
                draw=black,
                loosely dashed
            }
        }
    },
    black and white/static/.code={
        \gdef\patternnumber{1}
    },
    black and white/cycle/.code={
        \blackandwhitecycletrue
        \gdef\patternnumber{1}
    },
    black and white pattern/.is choice,
    black and white pattern/0/.style={},
    black and white pattern/1/.style={    
            draw=white,
            postaction={
                draw=black,
                dash pattern=on 2pt off 2pt
            }
    },
    black and white pattern/2/.style={    
            draw=white,
            postaction={
                draw=black,
                dash pattern=on 4pt off 4pt
            }
    },
    black and white pattern/3/.style={    
            draw=white,
            postaction={
                draw=black,
                dash pattern=on 4pt off 4pt on 1pt off 4pt
            }
    },
    black and white pattern/4/.style={    
            draw=white,
            postaction={
                draw=black,
                dash pattern=on 4pt off 2pt on 2 pt off 2pt on 2 pt off 2pt
            }
    },
    zoomboxarray inner gap/.initial=5pt,
    zoomboxarray columns/.initial=2,
    zoomboxarray rows/.initial=2,
    subfigurename/.initial={},
    figurename/.initial={zoombox},
    zoomboxarray/.style={
        execute at begin picture={
            \begin{scope}[
                spy using outlines={%
                    zoombox paths,
                    width=\imagewidth / \pgfkeysvalueof{/tikz/zoomboxarray columns} - (\pgfkeysvalueof{/tikz/zoomboxarray columns} - 1) / \pgfkeysvalueof{/tikz/zoomboxarray columns} * \pgfkeysvalueof{/tikz/zoomboxarray inner gap} -\pgflinewidth,
                    height=\imageheight / \pgfkeysvalueof{/tikz/zoomboxarray rows} - (\pgfkeysvalueof{/tikz/zoomboxarray rows} - 1) / \pgfkeysvalueof{/tikz/zoomboxarray rows} * \pgfkeysvalueof{/tikz/zoomboxarray inner gap}-\pgflinewidth,
                    magnification=3,
                    every spy on node/.style={
                        zoombox paths
                    },
                    every spy in node/.style={
                        zoombox paths
                    }
                }
            ]
        },
        execute at end picture={
            \end{scope}
            \node at (image.north) [anchor=north,inner sep=0pt] {\subcaptionbox{\label{\pgfkeysvalueof{/tikz/figurename}-image}}{\phantomimage}};
            \node at (zoomboxes container.north) [anchor=north,inner sep=0pt] {\subcaptionbox{\label{\pgfkeysvalueof{/tikz/figurename}-zoom}}{\phantomimage}};
     \gdef\patternnumber{0}
        },
        spymargin/.initial=0.5em,
        zoomboxes xshift/.initial=1,
        zoomboxes right/.code=\pgfkeys{/tikz/zoomboxes xshift=1},
        zoomboxes left/.code=\pgfkeys{/tikz/zoomboxes xshift=-1},
        zoomboxes yshift/.initial=0,
        zoomboxes above/.code={
            \pgfkeys{/tikz/zoomboxes yshift=1},
            \pgfkeys{/tikz/zoomboxes xshift=0}
        },
        zoomboxes below/.code={
            \pgfkeys{/tikz/zoomboxes yshift=-1},
            \pgfkeys{/tikz/zoomboxes xshift=0}
        },
        caption margin/.initial=4ex,
    },
    adjust caption spacing/.code={},
    image container/.style={
        inner sep=0pt,
        at=(image.north),
        anchor=north,
        adjust caption spacing
    },
    zoomboxes container/.style={
        inner sep=0pt,
        at=(image.north),
        anchor=north,
        name=zoomboxes container,
        xshift=\pgfkeysvalueof{/tikz/zoomboxes xshift}*(\imagewidth+\pgfkeysvalueof{/tikz/spymargin}),
        yshift=\pgfkeysvalueof{/tikz/zoomboxes yshift}*(\imageheight+\pgfkeysvalueof{/tikz/spymargin}+\pgfkeysvalueof{/tikz/caption margin}),
        adjust caption spacing
    },
    calculate dimensions/.code={
        \pgfpointdiff{\pgfpointanchor{image}{south west} }{\pgfpointanchor{image}{north east} }
        \pgfgetlastxy{\imagewidth}{\imageheight}
        \global\let\imagewidth=\imagewidth
        \global\let\imageheight=\imageheight
        \gdef\columncount{1}
        \gdef\rowcount{1}
        \gdef\zoomboxcount{1}
    },
    image node/.style={
        inner sep=0pt,
        name=image,
        anchor=south west,
        append after command={
            [calculate dimensions]
            node [image container,subfigurename=\pgfkeysvalueof{/tikz/figurename}-image] {\phantomimage}
            node [zoomboxes container,subfigurename=\pgfkeysvalueof{/tikz/figurename}-zoom] {\phantomimage}
        }
    },
    color code/.style={
        zoombox paths/.append style={draw=#1}
    },
    connect zoomboxes/.style={
    spy connection path={\draw[draw=none,zoombox paths] (tikzspyonnode) -- (tikzspyinnode);}
    },
    help grid code/.code={
        \begin{scope}[
                x={(image.south east)},
                y={(image.north west)},
                font=\footnotesize,
                help lines,
                overlay
            ]
            \foreach \x in {0,1,...,9} { 
                \draw(\x/10,0) -- (\x/10,1);
                \node [anchor=north] at (\x/10,0) {0.\x};
            }
            \foreach \y in {0,1,...,9} {
                \draw(0,\y/10) -- (1,\y/10);                        \node [anchor=east] at (0,\y/10) {0.\y};
            }
        \end{scope}    
    },
    help grid/.style={
        append after command={
            [help grid code]
        }
    },
}

\newcommand\phantomimage{%
    \phantom{%
        \rule{\imagewidth}{\imageheight}%
    }%
}
\newcommand\zoombox[2][]{
    \begin{scope}[zoombox paths]
        \pgfmathsetmacro\xpos{
            (\columncount-1)*(\imagewidth / \pgfkeysvalueof{/tikz/zoomboxarray columns} + \pgfkeysvalueof{/tikz/zoomboxarray inner gap} / \pgfkeysvalueof{/tikz/zoomboxarray columns} ) + \pgflinewidth
        }
        \pgfmathsetmacro\ypos{
            (\rowcount-1)*( \imageheight / \pgfkeysvalueof{/tikz/zoomboxarray rows} + \pgfkeysvalueof{/tikz/zoomboxarray inner gap} / \pgfkeysvalueof{/tikz/zoomboxarray rows} ) + 0.5*\pgflinewidth
        }
        \edef\dospy{\noexpand\spy [
            #1,
            zoombox paths/.append style={
                black and white pattern=\patternnumber
            },
            every spy on node/.append style={#1},
            x=\imagewidth,
            y=\imageheight
        ] on (#2) in node [anchor=north west] at ($(zoomboxes container.north west)+(\xpos pt,-\ypos pt)$);}
        \dospy
        \pgfmathtruncatemacro\pgfmathresult{ifthenelse(\columncount==\pgfkeysvalueof{/tikz/zoomboxarray columns},\rowcount+1,\rowcount)}
        \global\let\rowcount=\pgfmathresult
        \pgfmathtruncatemacro\pgfmathresult{ifthenelse(\columncount==\pgfkeysvalueof{/tikz/zoomboxarray columns},1,\columncount+1)}
        \global\let\columncount=\pgfmathresult
        \ifblackandwhitecycle
            \pgfmathtruncatemacro{\newpatternnumber}{\patternnumber+1}
            \global\edef\patternnumber{\newpatternnumber}
        \fi
    \end{scope}
}


\begin{document}

\begin{figure}[ht]\centering
\begin{tikzpicture}[
    zoomboxarray,black and white=cycle,
]
    \node [image node] { \includegraphics[width=0.45\textwidth]{gallery} };
    \zoombox{0.27,0.9}
    \zoombox[color code=red,magnification=6]{0.4,0.83}
    \zoombox{0.42,0.45}
    \zoombox[magnification=5]{0.95,0.52}
\end{tikzpicture}
\caption{The National Gallery of Canada}
\end{figure}

\begin{figure}[ht]\centering
\begin{tikzpicture}[
    zoomboxarray
]
    \node [image node] { \includegraphics[width=0.45\textwidth]{gallery} };
    \zoombox{0.27,0.9}
    \zoombox[color code=red,magnification=6]{0.4,0.83}
    \zoombox{0.42,0.45}
    \zoombox[magnification=5]{0.95,0.52}
\end{tikzpicture}
\caption{The National Gallery of Canada}
\end{figure}

\end{document}

答案2

clip,trim=<llx> <lly> <urx> <ury>您可以使用选项创建较小的图像\includegraphicstrim您也可以使用viewport)。我将使用简单的tabular环境两个 2x2 单元格进行对齐。对于大图,我将使用 TikZ 在其上绘制红色矩形,如图所示使用 TikZ 在图像上绘图

还有一个spy用于缩小区域的 TikZ 库,它也可以绘制这样的矩形。但在这里使用它可能会有点过头,而且实际上比手动操作更复杂。

答案3

我只是强调了裁剪方法,因为放入子图中似乎很简单。如果你没有要测试的图像,请从下载一个我之前的帖子

在此处输入图片描述

编译以下代码

  • 如果xelatex图像类型为 PNG、JPG、PDF 或 EPS
  • 或者latex-dvips-ps2pdf如果图像是 EPS 类型。

另请参阅上面给出的链接以了解如何使用 PSTricks 和管理图像包含的详细信息。

XeLaTeX 在裁剪方面似乎不太聪明!我注意到裁剪边缘附近有过多的空白。但实际上几乎可以忽略不计。

\documentclass{article}
\usepackage{graphicx}
\usepackage{pstricks,pst-node}

\def\Scale{1}

\newsavebox\IBox
\savebox\IBox{\includegraphics[scale=\Scale]{Images/hen}}

\psset
{
    xunit=\dimexpr(\wd\IBox/10)\relax,
    yunit=\dimexpr(\ht\IBox/10)\relax
}

\parindent=0pt

\begin{document}
\pspicture(\wd\IBox,\ht\IBox)
\rput[bl](0,0){\usebox\IBox}
\psgrid[style=gridstyle]
\pnode(1,7){a}
\pnode(4,10){b}
\psframe[linecolor=blue](a)(b)
\endpspicture
\hfill
\psscalebox{2}{%
\pspicture(1,7)(4,10)
\pnode(1,7){A}
\pnode(4,10){B}
\psclip{\psframe(A)(B)}
\rput[bl](0,0){\usebox\IBox}
\endpsclip
\psframe[linecolor=blue](A)(B)
\endpspicture}
\psset{linecolor=red}
\ncline{a}{A}
\ncline{b}{B}

\end{document}

答案4

在此处输入图片描述

\documentclass{article}
\usepackage[a4paper,margin=2cm,showframe=false]{geometry}
\usepackage{graphicx}
\usepackage{pst-node}
\usepackage{subfig}


\newsavebox\Original
\savebox\Original{\includegraphics{Images/hen}}

\newsavebox\IBox
\savebox\IBox{\includegraphics[width=0.4\textwidth]{Images/hen}}

\pstFPdiv\scale{\the\wd\Original}{\the\wd\IBox}


\psset{
   xunit=\dimexpr(\wd\IBox/10)\relax,
   yunit=\dimexpr(\ht\IBox/10)\relax,
   linewidth=2pt}


\newcommand\CreateSubFig[6]{%
    \psframe[linecolor=#6](#2,#3)(#4,#5)%
    \expandafter\gdef\csname#1\endcsname{%
        \begingroup
        \fboxsep=0pt\fboxrule=\pslinewidth\color{#6}\fbox{%
        \includegraphics[
            width=\dimexpr0.2\textwidth-2\fboxsep-2\fboxrule\relax,
            viewport=
                {#2\dimexpr\scale\psxunit\relax}
                {#3\dimexpr\scale\psyunit\relax}
                {#4\dimexpr\scale\psxunit\relax}
                {#5\dimexpr\scale\psyunit\relax},
            clip]{Images/hen}}%
        \endgroup}}

\newcommand\MainFig{%
    \pspicture(\wd\IBox,\ht\IBox)
    \rput[bl](0,0){\usebox\IBox}
    \psgrid[style=gridstyle]
    \CreateSubFig{One}{1}{7}{4}{10}{red}
    \CreateSubFig{Two}{6}{6}{9}{9}{green}
    \CreateSubFig{Three}{2}{3}{5}{6}{blue}
    \CreateSubFig{Four}{3.5}{0}{6}{2.5}{yellow}
    \endpspicture}

\begin{document}

\figure[hbtp]
\centering
\subfloat{\MainFig}\hspace{0.05\textwidth}
\subfloat[Sliced chicken]{%
    \vbox{%
        \offinterlineskip
        \halign{%
            #&\hskip3pt#\cr
            \One&\Two\cr
            \noalign{\vskip3pt}%
            \Three&\Four\cr}}}
\caption{This is my pet!}
\endfigure

\end{document}

相关内容