ImageMagick: scale JPEG image with a maximum file-size

Solution 1:

To restrict the resulting image to a maximum file size, you can use the commandline parameter -define jpeg:extent=max_value, like this:

convert original.jpeg -define jpeg:extent=300kb output.jpg
convert original.jpeg -define jpeg:extent=300kb -scale 50% output.jpg
convert original.jpeg -define jpeg:extent=300kb [...other options...] output.jpg

Note, this will not always work to match the exact size you wanted. You may have asked for 40kb output size, where input is 300kb, and get a result of 48kb.


(Update/Clarification: Output file size may be a bit lower or higher than your file requested size.)

Solution 2:

The jpegoptim tool (actual homepage is for multiple programs) works better for me:

jpegoptim -s -S8 *.JPG
  • -s means to strip all metadata (EXIF, JFIF, XMP, etc.)
  • -S8 means to target a filesize of about 8 KiB

You can crunch them even better by running it twice, because empirically, most images are smaller as progressive:

jpegoptim -s --all-progressive -S8 *.JPG; jpegoptim -s --all-normal -S8 *.JPG

jpegoptim will normally refuse to write an image that increases the size, so this will give you optimum quality/size.

As for the image dimensions part: You normally define a target size in terms of dimensions first and scale there, only then you define the target file size. This is because, when you display it, you ideally want the image dimensions being an integer multiple or fraction of the final display dimensions, to make scaling easier, or even unnecessary. So, scale to the target dimensions first (with quality 100, and possibly other things like 4:4:4 chroma, and most certainly with dct float), then downsize the file. If you can’t get to the file size range you want, choose smaller target dimensions and restart (from the original image, not the one you scaled down first).