Closed Albertbol closed 4 years ago
Are you able to provide a sample image that helps explain the question?
Sure Original image: Resized: Of course i understand that its a huge downsize, i made to 600px height also just to show blurry effect, its better quality than 200px height but still far from original image quality:
Thanks, to help me understand your expectations, are you able to produce an image at the same dimensions using a different application to demonstrate how sharp compares?
The default resizing kernel used for downsampling by sharp (and libvips) is Lanczos 3, which usually produces the best results for the vast majority of cases.
In your code sample, I note you've set kernel
to the undefined sharp.kernel.kernel
so it will default to "lanczos3", plus you're passing an ignored kernel
property to jpeg()
.
JPEG is lossy, even at "100% quality", so perhaps try the lossless PNG format for output.
You might want also to explore changing the fastShrinkOnLoad
property on resize()
.
https://sharp.pixelplumbing.com/en/stable/api-resize/#resize https://sharp.pixelplumbing.com/en/stable/api-output/#jpeg
1) fastShrinkOnLoad: true or fastShrinkOnLoad: false didnt change the output quality. 2) Can i ask how to convert image?
await sharp(tmpFilePath)
.resize(null, 200, {
kernel: sharp.kernel.kernel
})
.toFormat('png')
.rotate()
.toFile(tmp200x200Path)
Still saving as a jpeg...
Your code should produce PNG output (toFormat
takes precedence over any filename extension - this is a tested scenario e.g. https://github.com/lovell/sharp/blob/master/test/unit/io.js#L526).
Were you able to produce an image at the same dimensions using a different application to demonstrate how sharp compares?
I'm also having some issues with blurry downscale resizing.
Original:
Sharp (200px width, auto height downscale)
Paint (200px width downscale)
For this example I took the advice of using fastShrinkOnLoad false
return Promise.resolve(sharpImageCopy
.resize(resize.width, resize.height, {
fastShrinkOnLoad: false
})
.jpeg({
quality: 100
})
.toBuffer()
});
After looking into this further, this may be an underlying vips issue as resize looks to be similar using vips-cli lanczos3.
vips resize image.jpg image-vips.jpg 0.1041666666666667 --kernel lanczos3
I think MS Paint uses GDI+ under the hood so will be either bilinear or bicubic interpolation:
According to https://stackoverflow.com/a/48855445/10952119 it seems MS Paint also sharpens the image with a convolution kernel after resizing. I tried this:
width=$(vipsheader -f width owl-black.jpg)
height=$(vipsheader -f height owl-black.jpg)
# size=$((width > height ? width : height))
# factor=$(bc <<< "scale=10; 200 / $size")
# vips resize owl-black.jpg x.v $factor --kernel cubic
hscale=$(bc <<< "scale=10; 200 / $width")
vscale=$(bc <<< "scale=10; 112 / $height")
vips resize owl-black.jpg x.v $hscale --vscale $vscale --kernel cubic
cat > mask.con <<EOF
3 3 1 0
0.0 -0.125 0.0
-0.125 1.5 -0.125
0.0 -0.125 0.0
EOF
vips conv x.v x.jpg mask.con --precision float
(I used bicubic interpolation instead of bilinear)
Output: vips 8.8.4
vips 8.9.0 (with this patch applied)
The patched vips image looks almost identical to the MS Paint one (try to switch the images in your browser at 500% zoom level). The owl's eye only looks more saturated in MS Paint, but I'm not sure if that's the "correct output".
@kleisauke @lovell unfortunately I am only just starting down the rabbit hole of image interpolation, I apologise for my lack or knowledge in this space. Is the performance of lanczos3 treated as undesired in this case or is it a trade off for some other criteria?
The use of bicubic interpolation can result in greater overshoot/halo/moire effects compared with Lanczos, but it depends on the source image.
I'll close this question as the ability to specify interpolator and convolution kernels are already available and supported in both libvips and sharp.
@lovell Please, provide a working solution to this issue. The homepage has tons of examples, and it is great, but isn't it ridiculous that the tool named "sharp" does not have any sample/info about how to make images sharp. I am creating thumbnails from big images and they are too blurry, I tried to use sharpen
with random numbers (no idea what they are, because there is no demo/examples given), but I am not satisfied with the outcome.
@Andrew-web-coder If there's a specific image you'd like help with, please open a new issue with the code you are using and ensuring you detail all of the approaches you've tried so far, including the useful (and very much not "ridiculous") suggestions in this issue to try different resizing kernels and applying a convolution kernel.
I know, documentation is hard, I really do. I just wish there were more demos, more explanation about what those kernels are, how each parameter affects the result, etc. I wish you good luck and energy to continue working on your amazing tool. Thanks.
FYI, I ended up not resizing and not sharping my images using this tool, because browsers do much better job. So I simply created large images and let browser to do the rest.
@Albertbol use this kernel: kernel: sharp.kernel.lanczos3
I also experience the same issue.
Source image (retina screen capture with selenium):
After resizing (png):
This helped me
.convolve({
width: 3,
height: 3,
kernel: [0.0, -0.125, 0.0, -0.125, 1.5, -0.125, 0.0, -0.125, 0.0],
})
Using kernel: sharp.kernel.lanczos3 look good to me in my case 800*800
Hey, First of all thanks for such a great library, i appreciate your time investment in this project for all of us!
Now to the question: I have high quality image 2980x3974 .jpg, i want to make it smaller to 200px height and i set auto width, but i get very blurry image back, cant figure out what settings i need to pass to have good quality sharp image back. Code snippet:
I tried to use sharpen only in one place, in two places, all possible options, tried kernel: 'cubic', but allways same result, with very blurry image.