How to find all images with a certain pixel size using command line?
I am trying to find all JPG images within a folder with subfolders that have either width or height below 300px.
This way I want to detect old thumbnails and delete them.
For sure I can find all images using find
:
find . -iname "*.jpg" -type f | ...
But what follows after the pipe? Which package can I use to detect picture attributes?
Solution 1:
You can use identify
from imagemagick
, and you can use the following command:
find . -iname "*.jpg" -type f -exec identify -format '%w %h %i' '{}' \; | awk '$1<300 || $2<300'
the use of -exec <command> '{}' \;
makes sure that your filename can have spaces in them, alternatively you can use
find . -iname "*.jpg" -type f | xargs -I{} identify -format '%w %h %i' {} | awk '$1<300 || $2<300'
where the -I{}
takes care of the same thing.
What I like about identify
is that you can specify the output format; in this case '%w %h %i'
which gives the width, height and full pathname of the image. Then the awk
expression only keeps those lines for which the image is smaller than the desired size.
Example of the output:
64 64 ./thumbsup.jpg
100 150 ./photomin.jpg
Edit: If you want the filenames only (for piping to rm
for instance), simply change $line
in the awk
statement to $3
, then it will only print the third column.
Solution 2:
This worked for me:
find . -iname "*.png" -type f -exec identify -format '%i %wx%h\n' '{}' \; | grep '75x75'
This is the output sample:
./2520161636481000.png 75x75
./2620160819191100.png 75x75
./2420181545550700.png 75x75
Solution 3:
I think the accepted answer is very good, but I wanted to add another possible solution ...
Although I use ImageMagick
tools most often now myself, netpbm
is an old friend for processing images. You can see the size of any format of image with the command:
anytopnm file | pamfile
This will generate output that looks like:
stdin: PPM raw, 1650 by 1275 maxval 255
To answer the question of "what follows after the pipe?", I use while read
more often than I use xargs
because it is more flexible. My netpbm
answer to the question looks like this:
find -iname \*.jpg | while read img; do \
anytopnm "$img" | pamfile | \
perl -ane 'exit 1 if $F[3]<300 || $F[5]<300' || rm -v "$img"; \
done