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

Does vips CLI use some default quality parameter while converting images? #571

Closed
rn4391 opened this issue Dec 15, 2016 · 20 comments
Closed
Labels

Comments

@rn4391
Copy link

rn4391 commented Dec 15, 2016

This is the original image that I am considering
https://cdn18.nnnow.com/web-images/medium/styles/Y1NM5TM5P4L/1474025249507/1.jpg

This is at Q=80 originally.

I used cwebp and libvips CLI to convert this JPG to WebP using the following commands
cwebp ~/Desktop/original.jpg -o ~/Desktop/original-cwebp.webp
vips copy ~/Desktop/original.jpg ~/Desktop/original-vips.webp

Using either of these commands, results in a strange artefact in the top right corner of the image.
However, if I specify either Q=80 or greater in either of these commands or use ImageMagick to do the conversion, then I don't get the artefact. What is the possible reason for this?

artefact
The image on the right is the converted webp. Note the block artefacts at the right hand side of the image.

@jcupitt
Copy link
Member

jcupitt commented Dec 15, 2016

Hi, vips webp write defaults to Q 75, the jpeg standard. ImageMagick seems to default to Q 80.

@jcupitt
Copy link
Member

jcupitt commented Dec 15, 2016

cwebp uses 75 as the default as well:

https://developers.google.com/speed/webp/docs/cwebp

So I think ImageMagick is the odd one out here.

@rn4391
Copy link
Author

rn4391 commented Dec 16, 2016

So I am actually using sharp for these transformations and maybe you and @lovell can help me understand how the quality parameter at sharp interacts with the quality parameter of libvips and the existing image quality.

This is the sequence of transformations that are being carried out where artefact appears in the output image.
originalImage (original Q=80) --> Height 400,Quality 80 (using sharp, or any other transformation other than height) --> Format WebP, Quality 80 (using sharp)

This is the sequence where the artefact does not appear.
originalImage (original Q=80) --> Format WebP, Quality 80 (using sharp)

Because sharp sets Q=80 by default, this would happen on any two successive transformations. What should be the quality settings on each of the steps to get the result without artefact and with quality 80, assuming that the operation has to be carried out in two steps and not one.

@lovell
Copy link
Member

lovell commented Dec 16, 2016

In terms of sharp, JPEG and WebP should both be considered lossy formats, in that you'll see compression artefacts creeping in with every decompression+compression round trip (lossless WebP support is coming soon).

A JPEG image at "80% quality" will be different to a WebP image at "80% quality" as the latter achieves a smaller file size by discarding more data.

@jcupitt
Copy link
Member

jcupitt commented Dec 16, 2016

Yes, I agree with @lovell. In your case 1. I think you are doing jpeg decompress -> webp compress -> webp decompress -> jpeg compress, and each of those compressions will introduce image errors.

I would use a lossless format for intermediates, or better still, do all the processing in a single pipeline.

@rn4391
Copy link
Author

rn4391 commented Dec 16, 2016

So converting the initial JPEG, Q-80 to PNG for all intermediate transformations and the final PNG in the required format and quality should work fine right?

@jcupitt
Copy link
Member

jcupitt commented Dec 16, 2016

png is extremely slow, I would use vips format, or failing that, tiff.

@jcupitt
Copy link
Member

jcupitt commented Dec 16, 2016

There's a benchmark resizing a large image on another issue:

$ time vips resize x.png y.png 0.5
real	5m0.482s
user	7m20.524s
sys	0m2.012s
$ time vips resize x.tif y.tif 0.5
real	0m21.668s
user	1m29.224s
sys	0m7.344s

So with png format, you are spending >90% of total CPU time just in libpng decompress/recompress.

png is much slower than jpg, even though the compression algorithm is very simple. Never use png for anything, unless you have to.

@rn4391
Copy link
Author

rn4391 commented Dec 17, 2016

Is there any particular reason why TIFF cannot be an output format (while writing to buffer) in sharp? Is it because of the larger size of TIFF images?

@jcupitt
Copy link
Member

jcupitt commented Dec 17, 2016

libtiff just makes it slightly fiddly to code. libvips 8.5 has tiff output to buffer support and I imagine sharp will add support once 8.5 is done.

@rn4391
Copy link
Author

rn4391 commented Dec 17, 2016

var pipeline = sharp(path.join(__dirname, "1.jpg"));
pipeline.webp().quality(80).withMetadata();
pipeline.toFile(path.join(__dirname, "1_sharp.webp"));

I use this and get no block artefacts.

var pipeline = sharp(path.join(__dirname, "1.jpg"));
pipeline.webp().resize(null, 399).quality(80).withMetadata();
pipeline.toFile(path.join(__dirname, "1_sharp_399.webp"));

However if I resize it down by just 1px (the original image has height 400px, i resize it down to 399px), i get a huge block artefact on the top right corner. Why is there so much difference? Is the operation divided internally into two parts? Now that it is a single pipeline, such an artefact shouldn't have appeared right?

Attaching the sample. The one on the left is resized with the artefact.
sharp_comparison

@jcupitt
Copy link
Member

jcupitt commented Dec 19, 2016

I was able to reproduce your problem at the command-line:

$ vips resize original.jpg x.webp[Q=80] .9975

If you load x.webp and have a look at the pixel values, you'll see a block at the top-right appears as pixel value 253 rather than 255. This sort of tiny difference is usually invisible, but with a white background and a hard edge, it can be seen on some screens.

This makes an image with no blocking:

$ vips resize original.jpg x.webp[Q=90] .9975

But of course the file is a little larger.

I think your solutions are:

  1. Use Q90.

  2. Use transparency rather than a white background. webp has a special compression mode which saves the alpha with higher quality than the colour pixels to address exactly this problem. I can see that it might not work in this case -- it looks as if there's no alpha available.

  3. Use png or jpg instead.

@rn4391
Copy link
Author

rn4391 commented Dec 20, 2016

But is this something that can be corrected? Because even in other examples, and I can share those as well, the artefact is always on the top-right side. Could this probably be some issue with libvips around how resizing is handled? Will this go away with the near-lossless and lossless settings that are to be added in libvips?

Also, another image example
https://drive.google.com/file/d/0B3CnCQhw6PquYzRZMlloUGM3YU0/view?usp=sharing
1r0wbqpynz
This image has part white and part transparent background.

If I resize it down to 100px width (command line vips), I start getting a border around the image which is probably because of the white to transparent transition

vips resize ~/1r0wBqpynZ.png ./olive.png 0.5
olive

@jcupitt
Copy link
Member

jcupitt commented Dec 20, 2016

vips resize won't work on images with alpha, it just does a simple shrink, and for alpha you need to do things like premultiplication. Try:

$ vipsthumbnail olive.png -o tiny.png -s 200

tiny

@rn4391
Copy link
Author

rn4391 commented Dec 20, 2016

Is this exposed via sharp? Also, for normal JPEG images, what performs better, vips resize or vipsthumbnail?

@jcupitt
Copy link
Member

jcupitt commented Dec 20, 2016

Oh, to answer your first question, this looks like a problem with webp, I don't think it's anything to do with libvips.

@jcupitt
Copy link
Member

jcupitt commented Dec 20, 2016

Yes, sharp's resize does this for you automatically.

@rn4391
Copy link
Author

rn4391 commented Dec 22, 2016

Is this something that was added in sharp v0.17? Because v0.16 gives the edge.

@lovell
Copy link
Member

lovell commented Dec 22, 2016

@RNanwani Yes, v0.17.0 improved things in certain situations - see lovell/sharp#605

@jcupitt
Copy link
Member

jcupitt commented Jan 4, 2017

Sorry, I missed this question:

Also, for normal JPEG images, what performs better, vips resize or vipsthumbnail?

vips thumbnail will be faster since it can exploit shrink-on-load. For example, for a 10k x 10k JPEG:

$ time vips resize wtc.jpg x.jpg .0136577037
real	0m0.709s
user	0m0.692s
sys	0m0.016s
$ time vips thumbnail wtc.jpg x2.jpg 128
real	0m0.318s
user	0m0.304s
sys	0m0.008s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants