按宽高比对图像排序


13

我正在尝试选择一些艺术图像以适应一些新的框架。我希望能够按接近特定长宽比的顺序对这些图像进行排序,然后通过诸如feh之类的图像按接近的递减顺序查看它们。

有一些光荣的单行Unix表达式吗?否则,几十行Python应该清除掉它。


3
您可以通过ImageMagick来拉长宽比,例如identify -format "%[fx:w/h]:%M\n" *.jpg。我不知道如何根据任意值的接近程度轻松进行排序。sort似乎不支持这种排序。
NN

好吧,基本上,您希望将这些数字转换为整数距离度量,然后可以将其传递给sort -n。看来您实际上可以使用ImageMagick进行所有数学运算。
derobert

Answers:


8

使用NN的ImageMagick注释作为线索,事实证明您可以将其作为-format输出的一部分进行任意计算。因此,一种可能的方法是:

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

应该做你想做的。请注意,其中的4/3是恒定的所需纵横比。您当然可以找到它作为前一个的输出identify(以匹配“最接近该图像”)。

为说明起见,我们以期望的宽高比与实际的宽高比为准。然后乘以大数并四舍五入。乘法和舍入是因为sort仅处理整数,而不处理有理数。

编辑

事实证明sort确实似乎在做理性,而不仅仅是整数。它甚至在Single Unix Specification(v4)中指定。因此,您可以摆脱该变通办法:

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

您在哪里找到了有关identify的-format选项的文档?我在手册页上什么都没看到,花了很多时间试图弄清楚这些东西:)。
terdon

哦,在我的系统上,您的命令似乎不起作用。我知道33333:cover.jpgcover.jpg是500x500。
terdon

2
@terdon好,那是因为它的比率是1/1,而不是4/3。4 / 3-1 = 1/3 = .333…。只需将4/3更改为所需的比率(听起来像是1/1)即可。这些文档通常以令人困惑的方式位于imagemagick.org/script/fx.php中。也花了我一段时间找到它们。
derobert

感谢您的链接。至于其余的,我是个白痴。我的测试文件夹中只有一个jpg(其余为png),因此由于只看到一条输出线,因此我认为这是理想的结果,并且标识声称该图像的纵横比为4/3。这就是我在周一晚上想想的结果……+1是一个优雅的解决方案。
terdon

好答案!有没有一种方法可以在所有不符合所需比例的图像的文件名上添加某种标签?
心理学家

3

好吧,最简单的方法是使用ImageMagick。对于基于debian的系统,它应该在Linux发行版的存储库中,运行:

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格式的图像大小)拆分为数组“大小”,然后打印第一个字段(图像名称)以及将图像长度除以其高度的结果。该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

2

您可以使用参考来计算每个纵横比的差。看起来像derobert的答案,但更简单:

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

嗯,显然排序确实有道理。我的印象是它没有……
derobert

2

长宽比只是一个数字,因此如果名称以长宽比为前缀,则可以根据图像名称浏览图像。通过在宽高比前面添加符号链接,您可以浏览按宽高比排序的图像。

以下观看者按预期工作。(即使是真实图像,feh也不会前进/后退-在我的系统上)

  • comix
  • eog(Gnome的眼睛/图像查看器)
  • 格温维尤

picd='/media/dat_ext4/pictures/jpg/misc'
srtd="$picd/ar-sort"   # directory to hold "sorted" symbolic links
mkdir -p "$srtd"              

find "$picd" -maxdepth 1 -type f -name "*" -print0 | 
  while IFS= read -d $'\0' -r file ; do
    [[ $(file -ib "$file") != image* ]] && continue  # skip non-image files
    ar="$(identify -format "%[fx:w/h]" "$file")"  
    slink="$(printf '%s/%06.4f %s' "$srtd" "$ar" "$(basename "$file")")"
    # make symbolic link in 'ar-sort' directory
    ln -s "$file" "$slink"  
    echo "$slink" 
  done 

进入ar-sort目录,然后从您感兴趣的任何起点(长宽比)进行浏览。

符号链接名称如下所示:

0.6732 Gold Bars.jpg
0.7242 Light Bulb.jpg
0.8022 Escher - Waterfall.jpg
1.3696 Old Typewriter.jpg
1.6000 King Tut.jpg

注意:如果您的语言环境设置使用的是点以外的其他十进制符号,则此方法将无效。很容易解决,但:stackoverflow.com/questions/12845997/...
JobjörnFolkesson

1

我通常的推理思路是在听到“接近度”的地方使用平方误差距离度量。当然可以使用绝对值,这会更快。该脚本将理想的宽高比作为参数,处理当前目录中的所有* .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"|"

请注意,它在gawk / awk内使用二次距离和计算:)(感谢@NN作为初始快捷方式)
Deer Hunter

您能否在回答中添加脚本说明?这样会更好。
NN 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.