アスペクト比で画像を並べ替える


13

新しいフレームに合うようにいくつかのアート画像を選択しようとしています。これらの画像を特定のアスペクト比への近接度でソートし、fehなどのような近接度の高い順に表示できるようにしたいと思います。

輝かしい1行のUnix式がありますか?そうでなければ、数十行のPythonでこれをクリアするはずです。


3
ImageMagick経由でアスペクト比を取得できますidentify -format "%[fx:w/h]:%M\n" *.jpg。任意の値への近さで簡単にソートする方法を知りません。sortそのようなソートをサポートしていないようです。
NN

基本的に、これらの数値を整数距離メトリックに変換し、それをsort -nに渡すことができます。ImageMagickで実際にすべての計算を実行できるようです。
デロバート

回答:


8

NNのImageMagickコメントをリードとして使用すると、-format出力の一部として任意の計算を実行できることがわかります。したがって、1つの可能な方法:

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

あなたがしたいことをする必要があります。4/3には一定の、望ましいアスペクト比があることに注意してください。もちろん、前の出力としてidentify(「この画像に最も近い」に一致する)を見つけることができます。

説明するために、私たちは望ましいアスペクト比と実際のアスペクト比の明白な違いを取っています。次に、大きな数を掛けて丸めます。乗算と丸めは、ソートが整数ではなく、有理数を処理するためです。

編集する

それは判明sort有理数だけではなく、整数を行うように見えるん。さらに、Single Unix Specification(v4)で指定されています。そのため、その回避策を取り除くことができます。

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

Identifyの-formatオプションに関するドキュメントはどこで入手しましたか?マニュアルページには何も表示されず、かなりの時間を費やして、ひどいことを理解しようとしました:)。
テルドン

ああ、私のシステムではコマンドが機能していないようです。33333:cover.jpgcover.jpgが500x500である場所を取得します。
テルドン

2
@terdonよく、それは4/3ではなく1/1の比率を持っているからです。4 / 3-1 = 1/3 = .333…。その4/3を希望する比率(1/1のように聞こえます)に変更するだけです。ドキュメントは、通常は混乱を招く方法でimagemagick.org/script/fx.phpにあります。それらを見つけるのにしばらくかかりました。
-derobert

リンクをありがとう。残りについては、私はばかでした。テストフォルダーにはjpgが1つしかなく(残りはpng)、出力行が1つしか見られなかったので、それが望ましい結果であり、そのIDが画像のアスペクト比が4/3であると主張していると想定しました。それは月曜日の夜に考えようとしたときに得られるものです...エレガントな解決策のために+1。
テルドン

いい答え!目的の比率に準拠していないすべての画像のファイル名に何らかのラベルを追加する方法はありますか?
メンタリスト

3

さて、これを行う最も簡単な方法は、ImageMagickを使用することです。Linuxディストリビューションのリポジトリにあるはずです。Debianベースのシステムでは、次を実行します。

sudo apt-get install imagemagick

ImageMagickスイートのプログラムの1つはで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コマンドは、3番目のフィールド(LxH形式の画像サイズ)を配列「サイズ」に分割し、1番目のフィールド(画像名)と画像の長さを高さで割った結果を出力します。この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}、イメージ形式である必要がある3つの大文字()を探します。それがわかったら、画像の名前と寸法を簡単に特定できます。

    入力ファイル名にスペースが含まれているとフィールド番号が混乱するため、ここではgawkを使用していません。最後に、スクリプトは画像の名前と、長さ/高さの除算の結果をsort数値で出力します。

利用可能なアスペクト比を単に閲覧するだけでは不十分な場合、目的のアスペクト比を持つ画像が少なくとも1つある場合は、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は、実際の画像であっても、システム上で前後に移動しません)

  • コミックス
  • eog(Eye of 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コマンドが含まれており、出力フィールドセパレーターをありそうもない文字に設定し、平方差を計算し、ペアの差|ファイル名を出力します。ソートが実行され、不要な情報(アスペクト比の2乗の差)が選別され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"|"

2次距離とgawk / awk内の計算を使用することに注意してください:)(最初のショートカットは@NNに感謝します)
ディアハンター

スクリプトの説明を回答に追加してください。それが良くなるでしょう。
NN
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.