用TikZ的fit库实现插图标注

TiKZ-PGF 2020-02-07 18:22  浏览 :5035
在使用插图时,往往需要对插图进行标,如添加说明、强调标记等。 用户通常会使用“绘图”、“Photoshop”、“GIMP”等工具通过图像编辑来实现插图标注。这是一种简单直接的方法,但这种方法会存在如下问题: - 需要额外的软件支持,降低了文档的独立性。 - 字体、字号无法与正文匹配,整体效果不协调。 - 无法生成矢量注释文字,缩放会发生变形。 - 不便于LaTeX文档后期修改、编辑和维护。 笔者写过一篇用[tikz-imagelabels宏包实现插图注解](https://wenda.latexstudio.net/article-5040.html "tikz-imagelabels宏包实现插图注解")专栏文章,但使用tikz-imagelabels宏包进行标注时,只能在一个插图中进行标注,如果有多个插图需要统一标注,则这个宏包使用不太方便。 为此,可以在LaTeX中采用TikZ绘图工具,通过其fit库及绘图命令(主要是`\\node`命令)实现标注。 ## 载入TikZ宏包和扩展库 在文档导言区,载入TikZ宏包和必要的扩展库: ```tex % 引入TikZ宏包 \\usepackage{tikz} % TikZ宏包扩展库 \\usetikzlibrary{fit}% 坐标适配 \\usetikzlibrary{positioning}% 坐标相对定位 \\usetikzlibrary{calc}% 坐标计算 \\usetikzlibrary{arrows.meta}% 箭头样式 ``` ## 定义辅助网格绘制命令 在进行图像标注时,为了能够快速定位,可以通过循环的方式,在需要标注的图像上绘制一个辅助网格,以提供坐标参考。为此,可以在导言区添加如下命令定义代码: ```tex \\newcommand{\\drawgrid}{ % 绘制辅助网络,坐标范围:(0, 0)--(1,1) \\draw[very thin, draw=gray, step=0.02] (0,0) grid (1,1); \\draw[thin, draw=red, xstep=0.1, ystep=0.1] (0,0) grid (1,1); \\foreach \\x in {0,1,...,9} { \\node [anchor=north] at (\\x/10,0) {\\tiny 0.\\x}; } \\node [anchor=north] at (1,0) {\\tiny 1}; \\foreach \\y in {0,1,...,9} { \\node [anchor=east] at (0,\\y/10) {\\tiny 0.\\y}; } \\node [anchor=east] at (0,1) {\\tiny 1}; }% ``` ## 为单幅插图添加标注 在`tikzpicture`环境中,用`\\node`命令结合`\\includegraphics`命令插入图像,注意将定位锚点设置在西南方向,也就是左下角位置。 用`scope`环境限定坐标区域为:`x={(img1.south east)},y={(img1.north west)}`。 用`\\node`命令绘制命名矩形,可能在其可选参数中用fit指定绘制坐标,该坐标可以用绝对坐标,也可以通过坐标计算得到。 根据各个`\\node`的名称,绘制表示关系的连线或其他标注。 为快速进行坐标定位,可以先用`\\drawgrid`命令绘制辅助网格,然后根据辅助网格确定需要绘制的坐标值。 标注完整代码为: ```tex \\begin{tikzpicture} % 载入图像(注意定位锚点为西南,也就是左下角) \\node[anchor=south west, inner sep=0](img1) at (0,0) {\\includegraphics[width=0.85\\textwidth]{02openreviewtools01}}; % 限定坐标区域 \\begin{scope}[x={(img1.south east)},y={(img1.north west)}] % 绘制坐标辅助网络 \\drawgrid % 利用fit库绘制命名矩形 \\node[fit={(0.145,0.89) (0.235,0.96)}, inner sep=0pt, draw=red, thick] (view) {}; \\node[fit={(0.23,0.53) ($(0.23, 0.53) + (0.07, 0.045)$)}, inner sep=0pt, draw=red, thick] (tools) {}; \\node[fit={(0.522,0.52) ($(0.522, 0.52) + (0.05, 0.045)$)}, inner sep=0pt, draw=red, thick] (annotation) {}; \\node[fit={(0.755,0.52) ($(0.755, 0.52) + (0.075, 0.045)$)}, inner sep=0pt, draw=red, thick] (open) {}; % 绘制箭头连线表示操作顺序(用node为连线添加标记) \\draw[-{Stealth[scale=0.8]}, blue, thick] (view.south) to [out=-90, in=180] node[midway,circle,fill=blue,inner sep=0pt,minimum size=3pt,yellow] {\\scriptsize \\sffamily 1}(tools.west); \\draw[-{Stealth[scale=0.8]}, blue, thick] (tools.east) to [out=0, in=180] node[midway,circle,fill=blue,inner sep=0pt,minimum size=3pt,yellow] {\\scriptsize \\sffamily 2}(annotation.west); \\draw[-{Stealth[scale=0.8]}, blue, thick] (annotation.east) to [out=0, in=180]node[midway,circle,fill=blue,inner sep=0pt,minimum size=3pt,yellow] {\\scriptsize \\sffamily 3} (open.west); \\end{scope} \\end{tikzpicture} ``` 其排版结果为: ![](https://pics.latexstudio.net/data/images/202002/11d84bdb7c2dc49.png) ## 为多幅插图添加标注 在`tikzpicture`环境中,用`\\node`命令结合`\\includegraphics`命令插入多幅图像,注意各个`\\node`之间的相对关系及将各个`\\node`的定位锚点设置在西南方向,也就是左下角位置。 用`scope`环境限定坐标区域为:`x={(img2.south east)},y={(img1.north west)}`(**根据具体插图关系设置**)。 用`\\node`命令绘制命名矩形,可能在其可选参数中用fit指定绘制坐标,该坐标可以用绝对坐标,也可以通过坐标计算得到。 根据各个`\\node`的名称,绘制表示关系的连线或其他标注。 为快速进行坐标定位,可以先用`\\drawgrid`命令绘制辅助网格,然后根据辅助网格确定需要绘制的坐标值。 标注完整代码为: ```tex \\begin{tikzpicture} \\node[anchor=south west, inner sep=0](img1) at (0,0) {\\includegraphics[width=0.45\\textwidth]{04importmenu}}; \\node[anchor=south west, inner sep=0, right=0.1 of img1](img2) {\\includegraphics[width=0.45\\textwidth]{05importicloud}}; \\begin{scope}[x={(img2.south east)},y={(img1.north west)}] % 绘制坐标辅助网络 % \\drawgrid % 利用fit库绘制命名矩形 \\node[fit={(0.23,0.92) (0.268, 0.96)}, inner sep=0pt, draw=blue, thick] (pdffold) {}; \\node[fit={(0.008,0.731) (0.073, 0.825)}, inner sep=0pt, draw=red, thick] (new) {}; \\node[fit={(0.008,0.4) (0.055, 0.445)}, inner sep=0pt, draw=red, thick] (import) {}; \\node[fit={(0.57,0.73) (0.66, 0.77)}, inner sep=0pt, draw=red, thick] (icloud) {}; \\node[fit={(0.69,0.92) (0.78, 0.96)}, inner sep=0pt, draw=blue, thick] (icloudroot) {}; \\node[fit={(0.81,0.92) (0.85, 0.96)}, inner sep=0pt, draw=blue, thick] (icloudpdf) {}; \\node[fit={(0.74,0.62) (0.79, 0.83)}, inner sep=0pt, draw=red, thick] (pdfname) {}; % 绘制箭头连线表示操作顺序 \\draw[-{Stealth[scale=0.8]}, blue, thick] (pdffold.west) to [out=180, in=90] (new.north); \\draw[-{Stealth[scale=0.8]}, red, thick] (new.east) to [out=0, in=180] node[midway,circle,fill=black,inner sep=0pt,minimum size=3pt,white] {\\scriptsize \\sffamily 1}(import.west); \\draw[-{Stealth[scale=0.8]}, red, thick] (import.east) to [out=0, in=180] node[midway,circle,fill=black,inner sep=0pt,minimum size=3pt,white] {\\scriptsize \\sffamily 2}(icloud.west); \\draw[-{Stealth[scale=0.8]}, red, thick] (icloud.east) to [out=0, in=180]node[midway,circle,fill=black,inner sep=0pt,minimum size=3pt,white] {\\scriptsize \\sffamily 3} (pdfname.west); \\draw[-{Stealth[scale=0.8]}, blue, thick] (icloudroot.east) to [out=0, in=180] (icloudpdf.west); \\draw[-{Stealth[scale=0.8]}, blue, thick] (icloudpdf.south) to [out=-90, in=45] (pdfname.north); \\end{scope} \\end{tikzpicture} ``` 其排版结果为: ![](https://pics.latexstudio.net/data/images/202002/0d9a232e17cb0a6.png) 由于坐标采用了归一化处理,采用TikZ的fit库完成标注后,插图的缩放并不会影响标注的位置,这就为后续代码维护带来了极大的方便。 Happy TikZing!
发布评论
登录后方可评论!点击登录
全部评论 (1)
latexstudio
1楼 · 2020-02-08 18:26

可以上传了,目录权限问题,迁移的时候没有注意。