更新如下
我希望标题能说明我想做什么。我有一张大图像,用于图像处理主题的论文,我想显示这张大图像,并放大框(通常具有相同的纵横比)。我还想在大图像上叠加彩色框以显示我正在放大的部分。以下是一个例子:
我目前通过获取大图像并将所需的缩放区域复制到单独的图像中,并创建叠加框架来实现这一点,所有这些都在 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
这是使用spy
Martin 提到的库的一个例子。我编写了几种样式,可用于创建放大数组,具有任意数量的行和列,放置在原始图像的任意一侧,具有可指定的间隙。放大将占用与原始图像相同的空间。
图像本身和放大倍数是subcaptionbox
es,这需要包。它们被分配了和subcaption
形式的标签,可以使用和进行引用。如果没有为 提供选项,则将假定默认名称为。<figurename>-image
<figurename>-zoom
\ref
\subref
figurename
tikzpicture
zoombox
放大的中心点以相对坐标指定: \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>
您可以使用选项创建较小的图像\includegraphics
(trim
您也可以使用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}