SixLabors / ImageSharp

:camera: A modern, cross-platform, 2D Graphics library for .NET
https://sixlabors.com/products/imagesharp/
Other
7.34k stars 847 forks source link

PNG to WebP conversion: some files 10x larger than with `cwebp` #2765

Closed PerplexDaniel closed 2 months ago

PerplexDaniel commented 2 months ago

Prerequisites

ImageSharp version

3.1.4

Other ImageSharp packages and versions

N/A

Environment (Operating system, version and so on)

Windows 11 23H2 Build 22631.3737

.NET Framework version

8.0

Description

When converting some PNG files to WebP using ImageSharp the output file is way larger than when using cwebp 1.4.0 (Google's WebP encoder).

For example, when the attached 9.01 MB PNG file is converted to WebP using ImageSharp the output image is 7.14 MB whereas cwebp creates an image of 392 kB, 18x smaller.

Setting a different quality on WebpEncoder does not seem to have any effect either which is strange.

I have seen this happen to random other PNG files too but obviously cannot conclude it happens to every PNG image out there.

Steps to Reproduce

  1. Store the image as img.png on your computer
  2. Create a console app (dotnet new console -n ImageSharpTest):
  3. cd ImageSharpTest
  4. dotnet add package SixLabors.ImageSharp
  5. Copy this code into Program.cs:
    
    using SixLabors.ImageSharp;

Directory.SetCurrentDirectory("D:\"); // Change to directory holding img.png using Image image = Image.Load("img.png"); image.SaveAsWebp("img.webp");


6. `dotnet run`
7. Observe `img.webp` has a file size of 7.14 MB.

If you downloaded **Precompiled WebP utilities and library** from [Google](https://developers.google.com/speed/webp/download), you can compare this to `cwebp` as follows:

1. `cwebp <path-to-img.png> -o img.webp`
2. Observe this yields an image of roughly 392 kB, that's 18x smaller.

### Images

![img](https://github.com/SixLabors/ImageSharp/assets/24297947/672460ce-4b0e-4be6-8da9-0ede0d498a2e)
JimBobSquarePants commented 2 months ago

@PerplexDaniel I thinkt his would have been better suited as a discussion.

It's likely cwep is using lossy encoding.

I can use the default lossy encoding options with the following code and return a 387Kb image.

using var img = Image.Load(@"C:\Users\james\Downloads\2765.png");

WebpEncoder encoder = new ()
{
    FileFormat = WebpFileFormatType.Lossy
};
img.SaveAsWebp($@"C:\Users\james\Downloads\2765.webp", encoder);
PerplexDaniel commented 2 months ago

@JimBobSquarePants Thank you for the super fast response.

Is there any way to configure Lossy as a default? This is used in the context of Umbraco CMS if that matters.

I thinkt his would have been better suited as a discussion.

Apologies, it felt like a bug compared to cwebp but I didn't know about the FileFormat setting. Feel free to move / close this of course.

JimBobSquarePants commented 2 months ago

I don't exactly know how Umbraco sets things up but it's likely not using a custom Configuration instance so using Configuration.Default. It's possible to update the default instance by registering your own encoders.

You'd put this somewhere in startup.

 Configuration.Default.ImageFormatsManager.SetEncoder(WebpFormat.Instance, new WebpEncoder() { FileFormat = WebpFileFormatType.Lossy });