67

I have a number of JPEG pictures which I would like to scale down. Another requirement is that the file size should not be larger than say 300kByte.

Is that possible, please help me with an example =)

Kurt Pfeifle
  • 78,224
  • 20
  • 220
  • 319
kungcc
  • 1,670
  • 5
  • 24
  • 45
  • http://www.fmwconcepts.com/imagemagick/downsize/index.php scales down where needed. Doesn't work for me with JP2 files on fedora 23 and OSX though (`fullsize` not defined after line 235). – Nemo Feb 02 '16 at 10:33

2 Answers2

95

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.)

Kurt Pfeifle
  • 78,224
  • 20
  • 220
  • 319
  • 2
    I think it is the other way around. You may get a smaller file than you ask for but not bigger - http://www.imagemagick.org/script/command-line-options.php#define – Mark Setchell Aug 12 '14 at 14:53
  • @MarkSetchell: My statement about output file size was maybe a bit un-precise. I did not mean to imply it's *always* larger than requested. It did want to show it's not *exactly* as requested. Also, ImageMagick sometimes changes behaviour with new releases, and I did not specifically test if this feature changed recently. – Kurt Pfeifle Aug 12 '14 at 18:48
  • @MarkSetchell `for x in *.JPG; do mogrify -define jpeg:extent=8192 $x; done` gets me a dozen files of around 12 kB, so bigger is also possible. – mirabilos Aug 18 '14 at 09:17
  • 9
    this seems only affect the quality factor, not geometry scaling. – 把友情留在无盐 Apr 26 '15 at 13:53
  • 3
    Sadly this option also makes small files bigger. Is there any way to only affect files which are larger then 300kb? – Witek Feb 08 '18 at 13:45
  • Will this approach always reduce the quality as the last step after it has performed the other specified options first? For example, in the second option above where you have both extent=300kb and -scale 50%, does it do the scaling first, before reducing the quality to 300kb? – kojow7 Apr 04 '19 at 16:55
  • 5
    @kojow7: In general, ImageMagick will execute all actions in the same order as are given on the command line. So indeed, your suspicion/suggestion is correct: you will likely get better quality results if you first scale down, then reduce the file size. – Kurt Pfeifle Apr 04 '19 at 18:08
13

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).

mirabilos
  • 4,473
  • 2
  • 42
  • 65
  • 2
    The same problem as `convert -define jpeg:extent=300kb ...`, it keeps image dimensions and decreases quality. – brablc Sep 04 '15 at 15:05
  • For JPEG-2000 images you'll get an error. Asked at https://github.com/tjko/jpegoptim/issues/32 – Nemo Feb 02 '16 at 10:25
  • 1
    @Nemo the question was about JPEG files, not about JPEG2000 files. Convert those to JPEG first. (JPEG2000 decoders are currently in the process of being removed from a lot of software due to bugs, security holes, and lack of actual JPEG2000 images in the wild.) – mirabilos Feb 02 '16 at 14:14
  • 1
    @mirabilos I know that, otherwise I wouldn't have prefixed my comment with "For JPEG-2000" – Nemo Feb 02 '16 at 19:07