10

I've been trying to find png image files a certain height (over 500px). I know that file will return image dimensions. Example:

$ file TestImg1a.png

TestImg1a.png: PNG image data, 764 x 200, 4-bit colormap, non-interlaced   

But I need to use this to find all files in a directory with a height over 500px. I know how to print out all files regardless of height:

find . -name '*.png' | xargs file | awk '{print $7 " " $1}'

But how do I limit the $7 to those results greater than 500?

6 Answers 6

13
exiftool -q -r -ext png -if '$ImageHeight > 500' -p '$Directory/$FileName' .
7

i know this is a bit overkill but, this will work every time (even if there are spaces in your filename) and regardless of how file displays the information.

find . -name '*.png' -exec file {} \; | sed 's/\(.*png\): .* \([0-9]* x [0-9]*\).*/\2 \1/' | awk 'int($1) > 500 {print}'

and it prints the dimensions of the picture and the file

explaination:

  1. find all files named *.png under . and for each do a file on it

  2. use sed to print only the filename and dimensions then re-order to print dimensions first

  3. use awk to test the first number (height of pic) making sure its greater than 500 and if it is print dimensions and file name, if not do nothing.

1
  • Thanks. I did have to make a slight change -- the $1 in the awk argument to $3. But this definitely got it for me. Oct 26, 2012 at 10:57
6

You can also use identify from ImageMagick:

find . -name \*.png -print0|xargs -0 identify -format '%h %f\n'|
awk '$1>500'|cut -d' ' -f2-

Or in OS X:

mdfind 'kMDItemFSName=*.png&&kMDItemPixelHeight>500' -onlyin .
5

I feel that something other than shell utilities would be more appropriate, e.g., Perl:

#!/usr/bin/perl

use File::Find;
use Image::Info qw(image_info dim);

find (\&check_height, './');

sub check_height {

  my $info = image_info( $_ );
  my ($width, $height) = dim( $info );
  print $_ . " has height $height\n" if ( $height > 500 );

}

Less dicking around with trying to parse out $7; just get the dimensions directly. Yes, you'll need the Image::Info module, but, on CentOS/RHEL, it's a standard package, so you can just run yum install perl-Image-Info.

2
  • 1
    While perl is a normally a great solution, it's not in this case, esp since I don't have Image::Info nor the option to install. Oct 26, 2012 at 10:59
  • 1
    The perl solution is somewhat faster than the find/file/awk one, which is nice, and on ubuntu derivates the image info module is available from apt-get install libimage-info-perl
    – rivimey
    Jan 4, 2014 at 14:44
0
find . -name '*.png' -exec file "{}" \+ | awk -F"(: +PNG image data|,| x )" '$4 > 500 {print $4" "$1}'
7
  • doesn't work: 96, ./4/45445106_w185.png: 86, ./4/404358x_w185.png: 86, ./4/404341x_w185.png: 80, ./4/475986_w185.png: 621, ./4/481693_w185.png: 667, ./4/42513x_w185.png: 86, ./4/404372x_w185.png: Oct 25, 2012 at 18:58
  • @tink, cast $7 to an int before comparison, i.e. int($7) > 500.. in the absence of casting awk is resorting to a literal string compare
    – iruvar
    Oct 25, 2012 at 19:49
  • Steve, where does that "," come from? My "file" doesn't produce that. But as Chandra said: you can explicitly force $7 to become an integer using the method pointed out in his comment.
    – tink
    Oct 25, 2012 at 19:54
  • your awk statement will only work if the filename has no spaces in it
    – h3rrmiller
    Oct 25, 2012 at 20:04
  • @tink the "," is part of what file returns in my environment. Oct 26, 2012 at 11:01
0

This solution will also work. The last part of the code (mv "$img" ./lowpixel) will move files below a specified width and height to a folder. In the following example all jpg images lower than 300x300 will be moved to a folder named lowpixel:

find -iname \*.jpg | while read img; do anytopnm "$img" | pamfile | perl -ane 'exit 1 if $F[3]<300 || $F[5]<300' || mv "$img" ./lowpixel; done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .