有人想出一种方法来自动排列在更大的矩形或页面中的几个图形或方框吗?
这是一个真实的例子:某人正在制作beamer
演示文稿。他有 4 或 5 个现成的图形,它们具有不同的长宽比。他想不考虑任何特殊顺序地分布这些图形,但希望幻灯片或多或少地填满,并且每个图形的高度或宽度可以“很好地”调整,而不一定是规则的或矩形的。
这样做的目的是尽量减少未使用的空间和/或使图片很好地对齐/调整大小。但是手动执行此操作需要大量的错误和尝试,并跟踪附近图像的类似强制宽度或高度。
例如,Google Images 和 Google+ 就使用这种技术来优化图片和帖子占用的空间:
假代码(会自动排列5个项目,顺序可能会丢失):
\begin{frame}
\begin{arrangedfigure}[5] %five boxes/images
\includegraphics{fig1} &
\includegraphics{fig2} &
\includegraphics{fig3} &
\minipage{text} &
\includegraphics{fig4}
\end{arrangedfigure}
\end{frame}
相关问题,处理此问题但不是以自动的方式:
答案1
我使用的是使文本适合 Latex 中的特定空间探索这个问题的各个方面。我没有重新排列任何项目,但假设我有一串 N 幅图像,要求我将它们塞入特定大小的矩形中。
我将每张图片都视为文本,并允许换行来创建行。到目前为止,我已经尝试了三个版本。
1) 原始版本,相对图形大小保持不变
2)使所有图形高度相同
3)手动调整缩放比例,非正式地避免图形高度和宽度的巨大差异,并且不要让最后一行大部分不完整。
我在图像周围画了一个框,以帮助我们判断框是否已满。修订版使用\raggedright
并\hfill
成功避免超出边距。
\documentclass{article}
\usepackage{scalerel}
\usepackage{fp}
\usepackage{xcolor}
\usepackage{fancyhdr}
\pagestyle{fancy}
\newcount\boxheight
\newcount\boxwidth
\newlength\constrainedwidth
\newsavebox\testbox
\newlength\currentwidth
\newcommand\aspect[1]{%
\boxheight=\ht#1\relax%
\boxwidth=\wd#1\relax%
\FPdiv\testaspect{\the\boxheight}{\the\boxwidth}%
%\testaspect\\% COMMENT THIS LINE TO REMOVE ASPECT-RATIO PRINTS
}
% TARGET-HEIGHT, TARGET-WIDTH, CONTENT, GUESS>NATURAL-WIDTH, dWIDTH
\newcommand\constraintext[5]{%
\def\svfboxsep{\the\fboxsep}%
\setlength\fboxsep{0pt}%
\setlength\constrainedwidth{#2}%
\sbox\testbox{\rule{#2}{#1}}%
%TARGET ASPECT RATIO\\% COMMENT THIS LINE TO REMOVE COMMENT
%V\\% COMMENT THIS LINE TO REMOVE COMMENT
\aspect{\testbox}%
\edef\aspectratio{\testaspect}%
\constrainsize{#1}{\aspectratio}{#3}{#4}{#5}%
\setlength\fboxsep{\svfboxsep}%
}
\newcommand\constrainsize[5]{%
\sbox{\testbox}{\fbox{\begin{minipage}[b]{#4}{#3}\end{minipage}}}%
\aspect{\testbox}%
\FPiflt{\testaspect}{#2}%
\setlength{\currentwidth}{#4}%
\addtolength{\currentwidth}{-#5}%
\constrainsize{#1}{#2}{#3}{\currentwidth}{#5}%
\else
\setlength\constrainedwidth{#1}%
\FPdiv\result{1.0}{#2}%
%RESET ANY OTHER COUNTERS, TO AVOID ITERATION CREEP
\setcounter{section}{0}%
\setcounter{figure}{0}%
% CHANGE \framebox TO \makebox TO REMOVE FRAME
\framebox[\result\constrainedwidth]{\hfill%
\scaleto{\begin{minipage}[b]{\currentwidth}\raggedright #3\end{minipage}}{#1}%
\hfill%
}%
\fi%
}
\newsavebox\Ab
\newsavebox\Bb
\newsavebox\Cb
\newsavebox\Db
\newsavebox\Eb
\newsavebox\Fb
\def\A{\usebox{\Ab}\hfill}
\def\B{\usebox{\Bb}\hfill}
\def\C{\usebox{\Cb}\hfill}
\def\D{\usebox{\Db}\hfill}
\def\E{\usebox{\Eb}\hfill}
\def\F{\usebox{\Fb}\hfill}
\def\AA{\textcolor{green}{\rule{3in}{2in}}}
\def\BB{\textcolor{red}{\rule{2in}{1in}}}
\def\CC{\textcolor{cyan!50}{\rule{1.75in}{2in}}}
\def\DD{\textcolor{blue!40}{\rule{1.5in}{2in}}}
\def\EE{\textcolor{blue}{\rule{2.25in}{2.25in}}}
\def\FF{\textcolor{red!20}{\rule{2.5in}{1.5in}}}
\def\testcase{%
\centering\constraintext{.999\textheight}{.999\textwidth}{%
\A\B\C\F\D\E%
\B\C\A\E\D\F%
\D\B\F\C\A\E%
\E\F\D\C\A\B%
\F\C\B\D\E\A%
}{3\textheight}{1ex}%May have to increase next-to-last argument if divide by 0
\clearpage
}
\begin{document}
\fancyhead[c]{Method 1: All images remain the same relative size}
\savebox{\Ab}{\AA}
\savebox{\Bb}{\BB}
\savebox{\Cb}{\CC}
\savebox{\Db}{\DD}
\savebox{\Eb}{\EE}
\savebox{\Fb}{\FF}
\testcase
\fancyhead[c]{Method 2: All images scaled to the same height}
\savebox{\Ab}{\AA}
\savebox{\Bb}{\scalerel*{\BB}{\AA}}
\savebox{\Cb}{\scalerel*{\CC}{\AA}}
\savebox{\Db}{\scalerel*{\DD}{\AA}}
\savebox{\Eb}{\scalerel*{\EE}{\AA}}
\savebox{\Fb}{\scalerel*{\FF}{\AA}}
\testcase
\fancyhead[c]{Method 3: Manually Scale images}
\savebox{\Ab}{\scalebox{.98}{\AA}}
\savebox{\Bb}{\scalebox{1.8}{\BB}}
\savebox{\Cb}{\scalebox{1.0}{\CC}}
\savebox{\Db}{\scalebox{1.0}{\DD}}
\savebox{\Eb}{\scalebox{.95}{\EE}}
\savebox{\Fb}{\scalebox{1.05}{\FF}}
\testcase
\end{document}
编辑:要回答 OP 关于图形垂直居中的问题,可以通过将图像定义为以基线为中心来实现。在 的情况下\includegraphics
,需要减去图像高度的 1/2。在我的 MWE 的情况下,可以使用可选参数获得 s\raisebox
的下移。\rule
\def\AA{\textcolor{green}{\rule[-1in]{3in}{2in}}}
\def\BB{\textcolor{red}{\rule[-.5in]{2in}{1in}}}
\def\CC{\textcolor{cyan!50}{\rule[-1in]{1.75in}{2in}}}
\def\DD{\textcolor{blue!40}{\rule[-1in]{1.5in}{2in}}}
\def\EE{\textcolor{blue}{\rule[-1.125in]{2.25in}{2.25in}}}
\def\FF{\textcolor{red!20}{\rule[-.75in]{2.5in}{1.5in}}}