Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poor maximum JPEG quality. #18

Closed
imazen-bot opened this issue Feb 5, 2015 · 19 comments
Closed

Poor maximum JPEG quality. #18

imazen-bot opened this issue Feb 5, 2015 · 19 comments

Comments

@imazen-bot
Copy link

The maximum JPEG quality is poor comparing to other tools, like ImageMagick or Photoshop.

The colors are lost even at quality=100.

See http://oserv.org/bugs/gd/ for original (.png) / GD(.gd.jpg) / ImageMagick (*.im.jpg) comparison.

Everything was done using maximum quality settings.

Was tested using php and perl, the results are the same.


@imazen-bot
Copy link
Author

Hurts me too - I'd have expected no artefacts at quality 100.

BTW, is there some "uncompressed" saving of JPEGs? I'd need them only as mjpeg stream for ffmpeg, any saved CPU load would be welcome.


Originally posted by phmarek (phmarek) on May 28 2012 via Bitbucket

@imazen-bot
Copy link
Author

afair jpeg8 and later offers lossless compression.

I did not test yet if the 100 quality goes lossless or if we need an extra option.


Originally posted by pierrejoye (Pierre Joye) on Apr 16 2013 via Bitbucket

@imazen-bot
Copy link
Author

The demo page ( http://oserv.org/bugs/gd/ ) now works again, I re-uploaded it.
Please take a look.


Originally posted by ChALkeR (ChALkeR) on Aug 05 2013 via Bitbucket

@ChALkeR
Copy link

ChALkeR commented Nov 27, 2015

Hi here =). I am the original issue reporter.

@ChALkeR
Copy link

ChALkeR commented Nov 27, 2015

The issue is still valid as of libgd 2.1.1.

@vapier
Copy link
Member

vapier commented Nov 28, 2015

if you could attach a small testcase, it would help

@ChALkeR
Copy link

ChALkeR commented Nov 28, 2015

@vapier
Testcase:

<?php
$image = imagecreatefrompng('test1.png');
header('Content-Type: image/jpeg');
imagejpeg($image, null, 100);

test1.png: http://oserv.org/bugs/gd/test1.png or http://oserv.org/bugs/gd/test.png



@pierrejoye
Copy link
Contributor

I am not sure what we can change here without providing full tables customization. We simply pass the value to jpeg_set_quality.

And you are right too, current jpeg support does not provide lossless write support.

Which command line or code did you use for imagick? Imagemagick does a lot of magics depending on the arguments :)

@ChALkeR
Copy link

ChALkeR commented Jun 2, 2016

@pierrejoye

convert test1.png default.jpg
convert test1.png -quality 100 100.jpg
convert test1.png -quality 90 90.jpg

Any of those are better than gd with quality 100.

@ChALkeR
Copy link

ChALkeR commented Jun 2, 2016

On -quality 89 imagemagick starts too look like libgd with quality 100.

@vapier
Copy link
Member

vapier commented Jun 3, 2016

comparing the convert -debug all -vvv logs, the difference seems to be:

-  Sampling factors: 1x1,1x1,1x1  # -quality 100
+  Sampling factors: 2x2,1x1,1x1  # -quality 89

and when i make a similar change to gd_jpeg.c, the quality improves:

     jpeg_set_defaults(&cinfo);
+    cinfo.comp_info[0].h_samp_factor = 1;
+    cinfo.comp_info[0].v_samp_factor = 1;

guess we should use the algos in imagemagick's jpeg.c to figure out what samp factors to use ?

@pierrejoye
Copy link
Contributor

pierrejoye commented Jun 3, 2016

The 1st one (q=100) could be done easily but may drastically increase the file size by default as you can see with the images in this report.

This special case is also very particular as it uses anti-aliasing text patterns which per se are impossible hard to compress nicely from a visual point of view.

The default sampling factor in recent libjpeg (turbo) targets photographies more than text or patterns. PNG fits better for that.

One thing I like to add for 2.3 is to expose the parameters for Codecs like jpeg or PNG. Can be handy.

@vapier
Copy link
Member

vapier commented Jun 3, 2016

i think a good trade off is to set the scale factor to 1x1 when quality is >= 90, otherwise let jpeg do its default (2x2).

i agree that exposing the lower API makes sense. let's split that into a new issue though ?

@pierrejoye
Copy link
Contributor

pierrejoye commented Jun 3, 2016

--- a/src/gd_jpeg.c
+++ b/src/gd_jpeg.c
@@ -307,6 +307,10 @@

        if(quality >= 0) {
                jpeg_set_quality(&cinfo, quality, TRUE);
+               if (quality >= 90) {
+                       cinfo.comp_info[0].h_samp_factor = 1;
+                       cinfo.comp_info[0].v_samp_factor = 1;
+               }
        }

        /* If user requests interlace, translate that to progressive JPEG */

should do it.

I will apply + test tomorrow.

@vapier
Copy link
Member

vapier commented Jun 3, 2016

lgtm!

@vapier
Copy link
Member

vapier commented Jun 3, 2016

our 4th oldest issue closed out! :D

pierrejoye added a commit that referenced this issue Jun 3, 2016
pierrejoye added a commit that referenced this issue Jun 3, 2016
* GD-2.2:
  #18 add exp and src images
@pierrejoye
Copy link
Contributor

:)

Also fixed the test to get the actual diff.

I will also try to add a better perceptual diff for the tests suite. The current is rather useless without threshold for these cases.

@ChALkeR
Copy link

ChALkeR commented Jun 3, 2016

Thanks!

vapier added a commit that referenced this issue Jun 3, 2016
vapier added a commit that referenced this issue Jun 4, 2016
vapier added a commit that referenced this issue Jun 4, 2016
vapier added a commit that referenced this issue Jun 4, 2016
@pierrejoye
Copy link
Contributor

@vapier Thanks for fixing the makefile :)

And as reference for future readers or doc about sampling http://www.impulseadventure.com/photo/chroma-subsampling.html

pierrejoye added a commit that referenced this issue Jun 4, 2016
* GD-2.2:
  fix #215 gdImageFillToBorder stack-overflow when invalid color is used
  tests: add bug_github_18 to gitignore #18
  tests: fix typo in test name #18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants