简体   繁体   中英

Imagesharp resizes my image larger than the original

I have a program in .NETCoreApp 3.1 and I use the SixLabors.ImageSharp version 2.1.3 to handle the processing of images in our CDN for all our sites. The application run in docker container linux and for testing locally, I use WSL2 with ubuntu.

We are planning to review all our image and provide better format with a compressed version et a webp version.

For now the objective was to use TunyPNG ( https://tinypng.com/developers/reference/do.net ) to provide a compressed and webp version from the original image and use Imagesharp to resize these versions in the different dimensions that exists.

The first tests were successfull but I found a problem. I had an original transparent PNG (587x444) with filesize of 244k. The compressed version is 70k and webp converted is 16k using TinyPNG API.

The process after is to resize these versions and then i have a problem. The webp version resized to 581x439 using Imagesharp library has a filesize of 266k.

Here is the part of the code:

...
using var image = Image.Load(absoluteFilePath, out var format);
image.Mutate(x => x.Resize(width, height));
using var fileStream = new FileStream(convertedAbsolutePath, FileMode.Create);
await image.SaveAsync(fileStream, format);
...

I tried to force webp encoder and decoder but no amelioration. With an image without transparent background, I don't have this problem. If I use TinyPNG to do the resize, i don't have this problem and the filesize is 14k.

Is there some configurations to change or is it a problem with the Imagesharp library?

You can compress the image more when you use a IImageEncoder in the SaveAsync instead of the format. For Webp the encoder would be WebpEncoder . That has a few properties that you can change for example the NearLosslessQuality or Quality , which you can decrease to get a smaller file size. If you want to use the same method to process multiple formats you can save them as IImageEncoder and put that in SaveAsync . An example how you could do that is the following:

using var image = Image.Load(absoluteFilePath, out var format);
image.Mutate(x => x.Resize(width, height));
var encoder = GetImageEncoder(format);
using var fileStream = new FileStream(convertedAbsolutePath, FileMode.Create);
await image.SaveAsync(fileStream, encoder);

Where GetImageEncoder(IImageFormat format) is defined the following:

static IImageEncoder GetImageEncoder(IImageFormat format) {
    if(format is WebpFormat) {
        return new WebpEncoder() {
            Quality = 20,
            NearLosslessQuality = 50,
        };
    } else if(format is PngFormat) {
        return new PngEncoder();
    }
    throw new NotSupportedException();
}

The Quality and NearLosslessQuality have to be in the range between 0 and 100, where a 100 is highest Quality and 0 is the worst.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM