我正在尝试选择一些艺术图像来适应一些新框架。我希望能够根据与特定纵横比的接近程度对这些图像进行排序,然后通过 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
如果您确实需要纵横比不仅仅是大小,尝试这样的事情:
简单的选择,假设您的图像名称没有空格:
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
命令根据图像大小比例对结果进行排序。更复杂的是,这个可以处理文件名中的空格:
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"|"