Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have several image files in a directory. These images are similar size and have same background color.

How can I make all images same size by adding background like this attached image?

enter image description here

share|improve this question
    
This is possible (hint: see -border under "Image Operators" in man convert). However, you do need a short program to do this and I won't write it in shell, so if you are willing to accept an answer in perl using Image::Magick, I can provide one. –  goldilocks Apr 1 at 16:19
    
do you know the largest dimensions beforehand? –  Jasper Apr 1 at 16:24
    
@TAFKA'goldilocks' you don't really need a script. –  terdon Apr 1 at 17:00
    
@terdon That's a ridiculously absurd "one liner" if you need to first iterate all the images to find the largest geometry. –  goldilocks Apr 1 at 17:13
    
@TAFKA'goldilocks' true, but I'm assuming that only needs to be done once, or that the OP will know the size before hand. –  terdon Apr 1 at 17:14

3 Answers 3

up vote 7 down vote accepted

This should work with all the image types that ImageMagick can handle without having to specify *.png, *.jpg, *.jpeg etc:

#!/bin/bash

images=$(identify -format '%f\n' * 2>/dev/null)

IFS=$'\n'
set -e

max_dims=$(
  identify -format '%w %h\n' $images 2>/dev/null |
  awk '($1>w){w=$1} ($2>h){h=$2} END{print w"x"h}'
  )

orig_dir=originals_$(date +%Y-%m-%d_%T)
mkdir "$orig_dir"
mv -- $images "$orig_dir"
cd "$orig_dir"

set +e

for image in $images; do
  convert -- "$image" -gravity Center -extent "$max_dims" "../$image"
done

This will move the original images into a dated directory in case the results are not desirable. Also, this will fail if, for whatever reason, the image files have newlines in their names.

This script could do with some more error messages to give a helpful indication if anything went wrong. But for now if there is any error moving the images (everything between the set -e and set +e), the script will exit. Hopefully this will avoid doing any irreversible damage.

Update

Now with awk script shamelessly plagiarised from @terdon's answer.

share|improve this answer
1  
I'd give you a +1 for "shameless" but I'd already upvoted you before (and it was your suggestion in the first place anyway) :) –  terdon Apr 1 at 21:05

As long as you select a target size that is larger than your largest image, you should be fine with the following:

mogrify -gravity Center -extent 200x200 -background white -colorspace RGB *png

The command above will change the original file, you might want to backup before running it. It uses mogrify from ImageMagick to resize all pngs in the current directory to 200x200px (-extent 200x200) by adding a white background (-background black) and centering the image (-gravity Center). The -colorspace RGB is needed to avoid errors like

mogrify.im6: Ignoring incorrect gAMA value when sRGB is also present `emacs-48x48.png' @ warning/png.c/MagickPNGWarningHandler/1754.

To make sure you don't loose any image data, ensure that the size you use is larger or as large as the largest image you have. To get that quickly, try:

file *png | awk -F, '{print $2}' | sort -nu

That should print the sizes of all images sorted and you can easily find the largest.


To appease goldilocks (:P), you can automate the whole process:

dimensions=$(file *png | cut -d, -f 2 | sort -u | 
            awk '($1>w){w=$1}($3>h){h=$3}END{print w"x"h}') && 
mogrify -gravity Center -extent $dimensions -background white -colorspace RGB *png; 
share|improve this answer
    
TIL the "file" command, nice! But does this line work to find out the largest width and heigth easily? Perhaps you should sort x and y size separately. –  Jasper Apr 1 at 17:01
    
@Jasper indeed, that's just a hack, quick'n dirty®. –  terdon Apr 1 at 17:13
    
+1 For at least providing some basic steps ;) @Jasper you got my vote too, BTW. –  goldilocks Apr 1 at 17:21
    
@TAFKA'goldilocks' I bowed before the altar of efficiency, see edit. Still no script :P. –  terdon Apr 1 at 17:45
1  
@Tetsu, my answer should work with all the image types that ImageMagick can handle. –  Graeme Apr 1 at 19:51

I took the opportunity to improve my bash skills and came up with this:

#!/bin/bash

maxx=0
maxy=0

# find largest dimension
for file in *.jpg ; do
  dim=$(identify "$file" | awk '{ print $3 }')
  xdim=$(echo $dim | cut -f1 -dx)
  ydim=$(echo $dim | cut -f2 -dx)
  if [ $xdim -gt $maxx ] ; then
    maxx=$xdim
  fi
  if [ $ydim -gt $maxy ] ; then
    maxy=$ydim
  fi
done

mkdir bordered

# resize and store new images in new folder
for file in *.jpg ; do
  dim=$(identify "$file" | awk '{ print $3 }')
  xdim=$(echo $dim | cut -f1 -dx)
  ydim=$(echo $dim | cut -f2 -dx)

  xborder=$(( ($maxx - $xdim ) / 2 ))
  yborder=$(( ($maxy - $ydim ) / 2 ))

  convert "$file" -bordercolor black -border ${xborder}x${yborder} "bordered/$file"

done

This should do the trick: it first loops over all files (change according to your needs) to find the largest width and height and then loops again to add the required borders (change the -bordercolor black part to suit your needs). The new files are stored in the "bordered" folder.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.