Page 1 of 1

Selective jpeg comression

Posted: 2015-10-29T02:57:54-07:00
by graohicusernew
I have a hundreds of jpg file, with different quality and file size. I would like to compress (lossy) them to reduce file size. The issue is I don't want to use a same command for all of them, because some of them are already heavily compressed and re-copression results in poor quality.

Is there a function to do the compression based on the size or quality?
e.g diong the compression ONLY if the size of the file is over 200kb or its quality is higher than 70, and completely ignore the rest.

Thanks.

Re: Selective jpeg comression

Posted: 2015-10-29T05:13:19-07:00
by snibgo
I would do this as a script, mostly because I don't care what the "quality" number is, but I do care what the image looks like.

The technique I use for my website is to find the greatest compression that gives no more than 1% RMSE from the original image. For ordinary photographs, I find that 1% difference is generally indistinguishable. So there is a trial-and-error loop, that compresses at a quality setting, finds the byte filesize and RMSE, and decides whether the result is good enough.

IM contains code for trial-and-error on filesize but not RMSE, so I had to code that myself.

Re: Selective jpeg comression

Posted: 2015-10-29T10:14:58-07:00
by fmw42
perhaps see http://www.imagemagick.org/script/comma ... php#define
jpeg:extent=value Restrict the maximum JPEG file size, for example -define jpeg:extent=400KB. The JPEG encoder will search for the highest compression quality level that results in an output file that does not exceed the value. The -quality option also will be respected starting with version 6.9.2-5. Between 6.9.1-0 and 6.9.2-4, add -quality 100 in order for the jpeg:extent to work properly. Prior to 6.9.1-0, the -quality setting was ignored.

Re: Selective jpeg comression

Posted: 2015-10-29T12:43:23-07:00
by graohicusernew
snibgo wrote:I would do this as a script, mostly because I don't care what the "quality" number is, but I do care what the image looks like.

The technique I use for my website is to find the greatest compression that gives no more than 1% RMSE from the original image. For ordinary photographs, I find that 1% difference is generally indistinguishable. So there is a trial-and-error loop, that compresses at a quality setting, finds the byte filesize and RMSE, and decides whether the result is good enough.

IM contains code for trial-and-error on filesize but not RMSE, so I had to code that myself.
Seems like a great idea. There is an online service tinypng.com, which is very good at reducing file size without any visible difference in quality.
While it usually reduces the size by 40 - 90 precent, there are times that it doesn't compress the file at all, probably because re-copression will results in poor visible quality.

I've tried many different tricks to get the same results with IM and other offline tools without success. But now I realized they probably use the same approach as you described.

It's surprising that this isn't already implemented in IM, because visible quality is much more relevant than any other factor, to decide how much a given file should be compressed.

Would you mind sharing your script if it's not proprietary? :)

Re: Selective jpeg comression

Posted: 2015-10-29T13:15:10-07:00
by snibgo
It's in a C program that I can't share, sorry. But the code is trivially simple: it converts with high compression (low "quality"), and compare finds the RMSE. If this is more than my threshold, it tries again with lower compression.

This is quite slow and imprecise. A better algorithm would do a binary chop or something.

I don't use my program to re-compress jpeg files. It would work, of course, but then I wouldn't be comparing the new compression with the genuine original, but with an image that has already been mangled by jpeg compression.

I don't know if two generations of jpeg compression gives a significantly worse image than a single generation that results in the same size.

Re: Selective jpeg comression

Posted: 2015-10-29T14:06:51-07:00
by graohicusernew
fmw42 wrote:perhaps see http://www.imagemagick.org/script/comma ... php#define
jpeg:extent=value Restrict the maximum JPEG file size, for example -define jpeg:extent=400KB. The JPEG encoder will search for the highest compression quality level that results in an output file that does not exceed the value. The -quality option also will be respected starting with version 6.9.2-5. Between 6.9.1-0 and 6.9.2-4, add -quality 100 in order for the jpeg:extent to work properly. Prior to 6.9.1-0, the -quality setting was ignored.
Thanks. I used this command:
mogrify -define jpeg:extent=100kb *.jpg.

That does the job for files that are larger than jpeg:extent value and reduces their size. But surprisingly it also re-compress the files that are already smaller than the jpeg:extent value, rather than ignoring them, which results in larger file size and lower visible quality.

I guess the optimal solution would be what snibgo described. It would be extremely useful to have the option to compress files based on RMSE rather than, say, file size or quality of 0-100.

Re: Selective jpeg comression

Posted: 2015-10-29T14:34:38-07:00
by fmw42
I do not know if mogrify will respect any -defines. Even for convert, I do not know if it will work only on files larger than requested. So snibgo's solution may be best.