I've no idea how this performs but ImageMagick has an identify application that I've got to learn over the last ten minutes. Better than anything, it has a -format argument where you can do maths!

find -iname '*.jpg' -exec identify -format "%[fx:w*h] %i\n" {} \+ | sort -g

Unfortunately, if you get above a certain size, you get scientific notation (eg 1.2*10^3) instead of an integer back from identify. Thankfully sort has a -g argument that will parse them out.

On the same files here, this version (not forking out to Perl) only take 60% of the time the Perl version does. That's not to say Perl is slow, but going into perl and subshelling back out is an unnecessary complication that's slowing things down (I think).

Mine still isn't ideal. Needing to parse numbers back to integers for sorting is fairly slow. Ideally you'd do this all internally in one language where the size remains as an integer throughout... But the above is the shortest, sharpest one-liner I can do.


If you're looking for a command-line tool, the following command will sort image files where the highest resolution comes first:

find . -iname "*.png" -o -iname "*.jpg" | perl -e '$f=sub{eval(`identify -format %w*%h ${\quotemeta(shift)} 2>/dev/null`)};print sort{$f->($b)<=>$f->($a)}<>'

I'm basically sorting the files using perl sort sub-subroutine where the key here is to call the identify command and eval its formatted output.

identify is available with the imagemagick package:

sudo apt-get install imagemagick

UPDATE:

The following command will also output the resolution:

find . -iname "*.png" -o -iname "*.jpg" | perl -e '$f=sub{`identify -format %w*%h ${\quotemeta(shift)} 2>/dev/null`};chomp&&print "$_\t".$f->($_) for sort{eval($f->($b))<=>eval($f->($a))}<>'

Example:

./foo bar.png   1600*900
./baz.png       1600*900
./img_0004.jpg  1280*720
./img_0006.jpg  1280*720
./img_0001.jpg  1280*720
./img_0003.jpg  1280*720
./img_0002.jpg  1280*720
./img_0005.jpg  1280*720
./launcher.png  385*632
./textfield.png 402*329
./foo2.png      202*229