imazen / imageflow

High-performance image manipulation for web servers. Includes imageflow_server, imageflow_tool, and libimageflow
https://docs.imageflow.io/
GNU Affero General Public License v3.0
4.14k stars 140 forks source link

jpeg Quality: bug or feature #624

Closed bes-internal closed 7 months ago

bes-internal commented 1 year ago

imagemagick reference:

$ magick convert -quality 90 orig.jpg im.jpg && identify -verbose im.jpg |egrep 'Quality|Filesize'
  Quality: 90
  Filesize: 5.2085MiB
$ magick convert -quality 88 orig.jpg im.jpg && identify -verbose im.jpg |egrep 'Quality|Filesize'
  Quality: 88
  Filesize: 5.1116MiB
$ magick convert -quality 60 orig.jpg im.jpg && identify -verbose im.jpg |egrep 'Quality|Filesize'
  Quality: 60
  Filesize: 2.72034MiB
$ magick convert -quality 30 orig.jpg im.jpg && identify -verbose im.jpg |egrep 'Quality|Filesize'
  Quality: 30
  Filesize: 1.86795MiB

imageflow:

$ imageflow_tool v1/querystring --in orig.jpg --out imageflow2.jpg --command "format=jpeg&jpeg.quality=90" --quiet && identify -verbose imageflow2.jpg |egrep 'Quality|Filesize'
  Quality: 76
  Filesize: 4.08833MiB
$ imageflow_tool v1/querystring --in orig.jpg --out imageflow2.jpg --command "format=jpeg&jpeg.quality=88" --quiet && identify -verbose imageflow2.jpg |egrep 'Quality|Filesize'
  Quality: 70
  Filesize: 4.08833MiB
$ imageflow_tool v1/querystring --in orig.jpg --out imageflow2.jpg --command "format=jpeg&jpeg.quality=60" --quiet && identify -verbose imageflow2.jpg |egrep 'Quality|Filesize'
  Filesize: 4.08833MiB
$ imageflow_tool v1/querystring --in orig.jpg --out imageflow2.jpg --command "format=jpeg&jpeg.quality=30" --quiet && identify -verbose imageflow2.jpg |egrep 'Quality|Filesize'
  Filesize: 4.08833MiB

version with removed files

$ rm imageflow2.jpg && imageflow_tool v1/querystring --in orig.jpg --out imageflow2.jpg --command "format=jpeg&jpeg.quality=90" --quiet && identify -verbose imageflow2.jpg |egrep 'Quality|Filesize'
  Quality: 76
  Filesize: 4.08833MiB
$ rm imageflow2.jpg && imageflow_tool v1/querystring --in orig.jpg --out imageflow2.jpg --command "format=jpeg&jpeg.quality=88" --quiet && identify -verbose imageflow2.jpg |egrep 'Quality|Filesize'
  Quality: 70
  Filesize: 3.76498MiB
$ rm imageflow2.jpg && imageflow_tool v1/querystring --in orig.jpg --out imageflow2.jpg --command "format=jpeg&jpeg.quality=60" --quiet && identify -verbose imageflow2.jpg |egrep 'Quality|Filesize'
  Filesize: 2.05989MiB

Questions:

  1. The file is not overwritten?
  2. But where did the quality field disappear from the last processing?
  3. Quality: bug or feature? Or an attempt to cheat?..
lilith commented 1 year ago
  1. I don't think overwriting the file is the default behavior. It shouldn't be returning status code 0 if the file already exists, though.
  2. Not sure what you mean by that. However, quality=30 in Imageflow and quality=30 in ImageMagick do not correlate whatsoever, as the codecs are different and the values have different meanings in every codec. Typically, you can set a drastically lower quality value in Imageflow and get the same visual quality. This makes file size benchmarks hard unless you have a comparison tool (I'm releasing one soon).
  3. Overwriting files silently isn't good, and thus not the default, but if a file already exists the tool probably should express that in a failing status code (I think). I'll add some integration test cases to make sure all behavior is defined. Could you explain what you mean by attempting to cheat?
bes-internal commented 1 year ago

I saw the main offer of this tool is "get higher-quality images with smaller file sizes". This raises some doubts even if you have new efficient implementation of algorithms. If you just use open libs implementations, then it's still not clear where the smaller file size is taken from, except at the downgrade of quality. Anyway but why the quality field (I don’t know how it is displayed or filled) has a value not equal as transferred to the tool? It would be convenient to use these data later. Why quality field disappear from out at low values?

lilith commented 1 year ago

We're not just using mozjpeg, we have adaptive algorithms to tune chroma and other data. What matters, in my opinion, are the following factors:

  1. Perceptual image quality
  2. File size and browser decoding speed
  3. Processing time
  4. Security, specifically resistance to malicious image files. Please take a look at https://www.cvedetails.com/vulnerability-list/vendor_id-1749/Imagemagick.html

ImageMagick's reported quality setting is bogus, and as I mentioned this value is meaningless as it does not translate into similar math or algorithms across codecs.

On Wed, Feb 8, 2023, 1:55 PM Vladimir Varlamov @.***> wrote:

I saw the main offer of this tool is "get higher-quality images with smaller file sizes". This raises some doubts even if you have new efficient implementation of algorithms. If you just use open libs implementations, then it's still not clear where the smaller file size is taken from, except at the downgrade of quality. Anyway but why the quality field (I don’t know how it is displayed or filled) has a value not equal as transferred to the tool. It would be convenient to use these data later.

— Reply to this email directly, view it on GitHub https://github.com/imazen/imageflow/issues/624#issuecomment-1423227143, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2LHZ5L74IQFIEGZGS53TWWQB5FANCNFSM6AAAAAAUVUJHFY . You are receiving this because you commented.Message ID: @.***>

lilith commented 1 year ago

If you select a set of images (say - 4 to 8), we can process them side-by-side with ImageMagick and Imageflow to compare the balance of visual quality and file size.