1

I'm trying to create shell script that returns the largest picture in total dimensions pixel size?

For example:

I have many directory over 7000+, each directory have images:

dir_1/
picture_1.png = 800x600
picture_2.png = 80x100
picture_3.png = 80x640
picture_4.png = 500x630

dir_2/
p_1.png = 800x600
p_2.jpeg = 800x1000
p_3.png = 180x1640
p_4.gif = 500x30

So the result expected is:

 the largest one in dir_1 is: picture_1.png 
 the largest one is dir_2 is: p_2.png 

So I was thinking is best way is to find out the total of dimensions after collect the figures .. therefor I try to create bash script with sips command that can collect the figures

Here example :

 for f in *;
 do
 far=$( cd $f/OEBPS/image/ | ls * | egrep 'jpg|png|jpeg')

 W=$( sips -g pixelWidth $far | cut -f 2 -d":" )
 H=$( sips -g pixelHeight $far | cut -f 2 -d":" )

 coll=$(expr $W + $H)
 echo $f total is: $coll
 cd -
 done

But got error on result.

Any idea or better way?

5
  • 1
    What error do you see? Apr 25, 2015 at 15:12
  • 1
    For the "largest" image, do you want to consider the perimeter or the area? Apr 25, 2015 at 15:18
  • Don't do "cd" in scripts. You can iterate from your current directory over the files too. And don't do "ls" in scripts. In bash, you can do: for f in $f/OEBPS/image/*{png,jpeg,jpg}. A ls will bite you if you have blanks and such in fillenames. Apr 25, 2015 at 17:18
  • Also, what if two or more images in the same directory have the same size ? Apr 25, 2015 at 22:00
  • I've fix by add identify "$image" 2> /dev/null ... anyhow thanks for your effort ... last think .. i want to the result print with urlencode for example file: tadlil kalamy fmt.png to be tadlil%20kalamy%20fmt.png I'm use MAC OS X Apr 25, 2015 at 22:46

2 Answers 2

3

here's a way to get the height and width in one step:

IFS=x read w h < <(identify "$file" | grep -oP '\d+x\d+(?=\+)')

identify is part of the ImageMagick package.

Your "$far" is surely not what you want:

for dir in */OEBPS/image/; do
    for image in "$dir"/*.{jpg,png,jpeg}; do
        IFS=x read w h < <(identify "$image" | grep -oP '\d+x\d+(?=\+)')
        echo $((w*h)) "$image"
    done | sort -n | tail -1 | {
        read size file
        echo "largest in $dir is $file"
    }
done

Actually, identify can take several files, so a more efficient technique:

for dir in */OEBPS/image/; do
    identify "$dir"/*.{jpg,png,jpeg} |
    awk '{split($(NF-6), a, /x/); split($0, b, /[[]/); print a[1]*a[2], b[1]}' |
    sort -n | tail -1 | {
        read size file
        echo "largest in $dir is $file"
    }
done

The awk command is a bit complicated because I want to handle image names that may contain spaces

3
  • first script seems is good but need little fix .. i got the result but in same-time i got error like: /OEBPS/image/*.png': No such file or directory @ error/blob.c/OpenBlob/2675 /OEBPS/image/*.jpeg': No such file or directory @ error/blob.c/OpenBlob/2675 seems the script try to find all dir with jpg,jpeg,png and print it to me just need to hide that Apr 25, 2015 at 22:25
  • add shopt -s nullglob before the for loop Apr 25, 2015 at 23:09
  • you could also discard identity's stderr: identity "..." 2>/dev/null Apr 25, 2015 at 23:13
0
#!/bin/bash
file=""
max=0
for f in /OEBPS/image/*{png,jpg,jpeg}
do
  id=$(identify "$f") 
  size=$(echo ${id} | sed -r 's/.* (JPEG|PNG) ([0-9]+)x([0-9]+) .*/\2*\3/')   
  area=$(($size))
  if (( area >= max ))
  then
    max=$area
    file="$f"
  fi
done
echo $max $file
  • Don't use ls for iterating over files in scripts - blanks in filenames will brake them.
  • Don't cd around.
  • We don't need sorting to find the biggest file by area.
  • For doing arithmetic in bash, you don't need expr, but $((a*b)).

Identify needs ImageMagick.

The sed-command will fail if your filename looks too close like the output of identify.

You must log in to answer this question.

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