按宽高比对图像进行排序

按宽高比对图像进行排序

我正在尝试选择一些艺术图像来适应一些新框架。我希望能够根据与特定纵横比的接近程度对这些图像进行排序,然后通过 feh 之类的东西按接近程度降序查看它们。

有没有一些出色的单行 Unix 表达式?否则,几十行 Python 就可以解决这个问题。

答案1

使用 NN 的 ImageMagick 注释作为线索,事实证明您可以让它执行任意计算作为其-format输出的一部分。所以,一种可能的方式:

identify -format "%[fx:round(100000*abs((4/3)-(w/h)))]:%M\n" *.jpg | \
    sort -n -k1 -t:

应该做你想做的事。请注意,4/3 是一个常数,即所需的长宽比。您当然可以发现它是前一个的输出identify(匹配“最接近此图像”)。

为了解释这一点,我们采用了期望纵横比和实际纵横比之间的明显差异。然后乘以一个大数,并四舍五入。乘法和舍入是因为排序只处理整数,而不处理有理数。

编辑

事实证明,sort它确实可以计算有理数,而不仅仅是整数。它甚至在单一 Unix 规范 (v4) 中被指定。因此,您可以摆脱该解决方法:

identify -format "%[fx:abs((4/3)-(w/h))]:%M\n" *.jpg | \
    sort -n -k1 -t:

答案2

那么,最简​​单的方法就是使用图像魔术师。它应该位于您的 Linux 发行版的存储库中,对于基于 debian 的系统,运行:

sudo apt-get install imagemagick

ImageMagick 套件的程序之一是identify,它将打印输入图像文件列表的特征。结合它sort会给你一个按大小排序的图像列表(你可以更改 png 为你拥有的任何扩展名:

identify *png | sort -gk 3

如果您确实需要纵横比不仅仅是大小,尝试这样的事情:

  1. 简单的选择,假设您的图像名称没有空格:

    identify *png *jpg *gif | \
    gawk '{split($3,sizes,"x"); print $1,sizes[1]/sizes[2]}' | \
    sed 's/\[.\]//' | sort -gk 3
    

    gawk 命令将第三个字段(格式为 LxH 的图像大小)拆分为数组“sizes”,然后打印第一个字段(图像名称)以及图像长度除以高度的结果。该sed命令只是美化输出,并且该sort命令根据图像大小比例对结果进行排序。

  2. 更复杂的是,这个可以处理文件名中的空格:

    find . \( -iname  "*png" -o -iname "*jpg" -o -iname "*gif" \) -exec identify {} \; |\
    perl -ne '/(.+?)\s+[A-Z]{3}\s+(\d+)x(\d+)/; print "$1 ", $2/$3, "\n"' | \
    sort -gk 2
    

    在这里,我们用来find识别我们感兴趣的文件并运行命令identify,然后通过一个小 PERL 脚本传输其输出。正则表达式查找三个大写字母 ( [A-Z]{3}),这应该是图像格式。一旦我们找到了这一点,就很容易识别图像名称和尺寸。

    我在这里没有使用 gawk,因为输入文件名中存在空格会混淆字段编号。最后,脚本将打印出图像的名称以及我们用数字表示的长度/高度除法的结果sort

如果仅仅浏览可用的宽高比还不够,如果您至少有一张具有所需宽高比的图像,只需使用 grep 提取那些比例最接近的图像:

identify *png *jpg *gif | \
gawk '{split($3,sizes,"x"); print $1,sizes[1]/sizes[2]}' |\
sed 's/\[.\]//' | sort -gk 3 | grep -C 10 GOOD_IMAGE.jpg

答案3

您可以计算每个纵横比与参考的差异。看起来像德罗伯特的答案,但更简单:

ref=4/3
identify -format "%[fx:abs(w/h - $ref)] %M\n" *.jpg | sort -n -k1

答案4

我通常的推理思路是,只要我听到“接近度”一词,就使用平方误差距离度量。当然可以使用绝对值,而且会更快。该脚本将以下参数作为参数理想的长宽比,处理当前目录中的所有 *.jpg 文件,并按照与理想比例的偏差升序排列输出。

head删除由 ImageMagick 插入的尾部行尾字符。

该脚本包含一个 gawk 命令,它将输出字段分隔符设置为不太可能的字符,计算平方差并打印回差|文件名对。执行排序并剔除不必要的信息(长宽比差的平方)cut

#!/bin/sh
if [ x"$1" = "x" ] ; then
  echo "Usage: $0 TargetAspectRatio" >&2
  exit 2
fi
ASPECT_CMD="BEGIN{OFS=\"|\";}\
{\
print (\$1-$1)^2, \$2;\
}"
identify -format "%[fx:w/h]:%M\n" *.jpg | head -n-1 | gawk -F":" "$ASPECT_CMD" | sort -k1 -t"|" | cut -f2 -d"|"

相关内容