自动裁剪图像以匹配 LaTeX 中并排图形的纵横比

自动裁剪图像以匹配 LaTeX 中并排图形的纵横比

我正在用 LaTeX 处理一个文档,需要将两张图片并排放置。这些图片的长宽比不同,我正在寻找一种方法来自动裁剪它们,以便在最终文档中以相同的长宽比显示。

下面是我用来并排放置图像的基本 LaTeX 模板:

\usepackage{graphicx}
\usepackage{subcaption}

\begin{figure}[htbp]
    \centering
    \begin{subfigure}[b]{0.45\linewidth}
        \includegraphics[width=\linewidth]{path/to/first/image}
        \subcaption{First Image}
        \label{fig:first_image}
    \end{subfigure}
    \hfill
    \begin{subfigure}[b]{0.45\linewidth}
        \includegraphics[width=\linewidth]{path/to/second/image}
        \subcaption{Second Image}
        \label{fig:second_image}
    \end{subfigure}
    \caption{Side-by-Side Images}
    \label{fig:both_images}
\end{figure}

我的目标是在 LaTeX 中自动调整(裁剪)这些图像,使它们在显示时具有匹配的宽高比。理想的解决方案是保持高度或宽度(以每幅图像中较大的为准)并裁剪另一个尺寸以匹配具有较低宽高比的图像的宽高比。

我知道 LaTeX 可能不是最有效的图像处理工具,但我很好奇是否有以 LaTeX 为中心的方法来实现这一点。如果需要,我愿意使用其他软件包或编写一些自定义命令。

答案1

我想分享一个我使用 PowerShell 脚本开发的解决方法,尽管它不是一个直接的 LaTeX 解决方案。

我编写了一个 PowerShell 脚本,可以自动使用 ImageMagick 调整两幅图像的宽高比。该脚本计算两幅图像的宽高比,确定哪幅图像的宽高比较大,然后从侧面裁剪该图像以匹配另一幅图像的宽高比。

以下是该脚本工作原理的简要概述:

  1. 加载图像:脚本加载两张指定路径的图像。

  2. 计算纵横比:它使用 ImageMagick 获取每个图像的尺寸并计算它们的纵横比。

  3. 确定种植要求:脚本识别需要裁剪哪个图像以匹配另一个图像的纵横比。

  4. 执行裁剪:然后对已识别的图像进行相应裁剪,并使用新名称保存输出,表明图像已被裁剪。

此 PowerShell 方法是一种变通方法,允许在将图像用于 LaTeX 文档之前对其进行预处理。它有助于确保图像在 LaTeX 文件中并排包含时符合纵横比。

我在此附加 PowerShell 脚本以供参考:

# Define the paths of the two images
$imagePath1 = "path\to\first\image.jpg"
$imagePath2 = "path\to\second\image.jpg"

# Use ImageMagick to get image dimensions
$dimensions1 = magick identify -format "%wx%h" $imagePath1
$dimensions2 = magick identify -format "%wx%h" $imagePath2



# Extract width and height
$width1, $height1 = $dimensions1 -split 'x' | ForEach-Object { [int]$_ }
$width2, $height2 = $dimensions2 -split 'x' | ForEach-Object { [int]$_ }


# Calculate aspect ratios
$aspectRatio1 = $width1 / $height1
$aspectRatio2 = $width2 / $height2


# Determine which image to crop and calculate new dimensions
if ($aspectRatio1 -gt $aspectRatio2) {
    $newWidth = [math]::Round($height1 * $aspectRatio2)
    $cropAmount = [math]::Round(($width1 - $newWidth) / 2)
    
    $imagePath = $imagePath1
    $height = $height1
}
elseif ($aspectRatio2 -gt $aspectRatio1) {
    $newWidth = [math]::Round($height2 * $aspectRatio1)
    $cropAmount = [math]::Round(($width2 - $newWidth) / 2)

    $imagePath = $imagePath2
    $height = $height2
}

# Assuming $imagePath contains the full path of the image
$imageDirectory = [System.IO.Path]::GetDirectoryName($imagePath)
$imageFileName = [System.IO.Path]::GetFileNameWithoutExtension($imagePath)
$imageExtension = [System.IO.Path]::GetExtension($imagePath)

# Constructing new file name with "_cropped" suffix
$newImageName = $imageFileName + "_cropped" + $imageExtension
$newImagePath = [System.IO.Path]::Combine($imageDirectory, $newImageName)


# Crop the image
magick convert $imagePath -crop $newWidth"x"$height"+"$cropAmount"+"0 +repage $newImagePath

对于那些熟悉基本脚本和 ImageMagick 的人来说,这个脚本是一种实用的方法,在处理大量图像时尤其有用。

我希望这个解决方法可能对面临类似挑战的其他人有所帮助。如果有人有建议,我仍然愿意接受任何特定于 LaTeX 的解决方案!

答案2

如果您指定了宽度,那么您需要做的就是裁剪具有较大高度的图像。

\documentclass{article}
\usepackage{adjustbox}
\usepackage{graphicx}
\usepackage{subcaption}

\begin{document}

\begin{figure}[htbp]
  \sbox0{\includegraphics[width=0.45\linewidth]{example-image-16x10}}%
  \sbox1{\includegraphics[width=0.45\linewidth]{example-image-10x16}}%
    \centering
    \begin{subfigure}[b]{0.45\linewidth}
      \ifdim\ht0>\ht1\relax
        \edef\crop{\the\dimexpr 0.5\ht0-0.5\ht1}%
        \adjustbox{clip,trim=0pt {\crop} 0pt \crop}{\usebox0}
      \else
        \usebox0
      \fi
      \subcaption{First Image}
      \label{fig:first_image}
    \end{subfigure}
    \hfill
    \begin{subfigure}[b]{0.45\linewidth}
      \ifdim\ht1>\ht0\relax
        \edef\crop{\the\dimexpr 0.5\ht1-0.5\ht0}%
        \adjustbox{clip,trim=0pt {\crop} 0pt \crop}{\usebox1}
      \else
        \usebox1
      \fi
      \subcaption{Second Image}
      \label{fig:second_image}
    \end{subfigure}
    \caption{Side-by-Side Images}
    \label{fig:both_images}
\end{figure}

\end{document}

答案3

我无法想象自动裁剪具有不同宽度和高度的图像的实用性,因为这样你无法控制每张图像中丢失的内容。

如果重点是保持每对图像内(而不是之间)的高度相同,并始终粘贴两个边距并填充文本宽度的 90%,即每对图像中没有不同的间隙,但两侧的宽度不一定相等,我的建议是只缩放而不裁剪任何东西。下一个 MWE 测试一个宏来自动执行此操作,以便清晰起见,不使用子图或浮点数。

姆韦

\documentclass[twocolumn]{article}
\usepackage{graphicx}
\usepackage[columnsep=2cm]{geometry}
\usepackage{settobox}
\usepackage{calc}
\parindent0pt
\parskip1em

\newlength{\WA}
\newlength{\HA}
\newlength{\WB}
\newlength{\HB}
\newsavebox{\boxA}
\newsavebox{\boxB}
\newlength{\XY}

\newcommand\img[2]{
\sbox{\boxA}{\includegraphics{#1}}\settoboxwidth{\WA}{\boxA}
\settoboxheight{\HA}{\boxA}\sbox{\boxB}{\includegraphics{#2}}
\settoboxwidth{\WB}{\boxB}\settoboxheight{\HB}{\boxB}
\par\resizebox{\linewidth}{!}{
\includegraphics[width=\dimexpr\WA*\HB/\HA,height=\HB,keepaspectratio]{#1}
\setlength{\XY}{\dimexpr((\WA*\HB/\HA)+\WB)}\hspace{.05\XY}%
\includegraphics[width=\WB,height=\HB,keepaspectratio]{#2}\par}}

\begin{document}

\img{example-image-16x9}{example-image-16x10}
\img{example-image-9x16}{example-image-10x16}
\img{example-image-16x9}{example-image-10x16}
\img{example-image-9x16}{example-image-16x10}
\img{example-image}{example-image-1x1}
\img{example-image-golden}{example-image-9x16}
\img{example-image-golden-upright}{example-image-9x16}
\img{example-image-golden-upright}{example-image-1x1}
\img{example-image-1x1}{example-image-golden-upright}

\end{document}

相关内容