Whenever I get photos from others after a trip, the photos tend to be huge.  Who the heck needs 20 megapixels anyway?  Four is plenty for me so the first thing I want to do to make the photos easier to deal with is resample them.  I use ImageMagick’s convert for this.  convert wants a percentage reduction. Here’s how you can calculate what percentage to use:
pc = ((desiredMP / ((originalpixelcountinx * originalpixelcountiny) / 1000000.)) ** 0.5) * 100
Of course, it’s helpful if all the photos that you have are the same size.  I use jhead to see the original size of the photo, but since we’re already talking ImageMagick here, identify works as well.  So, if your original photo size was 5312×2988 and you want four megapixel output, then you calculate the percentage for convert like this:
>>> ((4 / ((5312 * 2988) / 1000000.)) ** 0.5) * 100
50.20080321285141
>>>
50% for these photos. Then you can run a little bash script to do the conversion:
for img in `ls *.JPG`
do
  convert -sample 50% $img small/$img
  echo "$img converted"
done
The reduced photos are written into a directory called “small” that must already exist. Now you can delete those huge photos since we’re not making billboards. 🙂
Update September 18, 2018:
I quickly wrote this code to deal with a directory of photos of varying sizes. The code still needs some work.
#!/usr/bin/python
import os
from PIL import Image
def shellquote(s):
  return "'" + s.replace("'", "'\\''") + "'"
sInDir = '.'
sFileType = 'jpg'
iTargetMP = 4
sOutDir = 'small'
lName = os.listdir(sInDir)
for sName in lName:
  if (sName[-3:].lower() == sFileType):
    mImage = Image.open(sName)
    iWidth, iHeight = mImage.size
    fPC = ((iTargetMP / ((iWidth * iHeight) / 1000000.)) ** 0.5) * 100
    iPC = int(fPC)
    #fix the filenames
    sInName = shellquote(sName)
    sOutName = shellquote('%s/%s' % (sOutDir, sName))
    if (iPC <= 99):
      sLine = 'convert -sample %i%% ' % iPC
    else:
      sLine = 'cp '
    sLine += '%s %s' % (sInName, sOutName)
    print sLine