ImageFactory is generating .webp file that is larger than .jpeg file

2.3k Views Asked by At

I have an ASP.NET Core based WebAPI. I am trying to convert uploaded .jpeg images to .webp. I tried using ImageProcessor library along with the ImageProcessor.Plugins.WebP to generate the .webp compressed file. Here is the code I used

public async Task<IActionResult> Store(IFormFile file)
{
    if(!ModelState.IsValid) 
    {
        return Problem("Invalid model!");
    }

    string absoluteFilename = Path.Combine("d:/uploaded_images", Path.GetRandomFileName() + ".webp");

    using var stream = new FileStream(absoluteFilename, FileMode.Create);
    using ImageFactory imageFactory = new ImageFactory(preserveExifData: false);
    imageFactory.Load(file.OpenReadStream())
                .Format(new WebPFormat())
                .Quality(100)
                .Save(stream);

    return Ok(absoluteFilename);
}

But the above code takes an 83.9KB JPEG file and created a 379KB WEBP file. I tried to convert my JPEG file to WEBP using an online converter and the outcome was 73KB.

How can I correctly convert the .jpeg file to .webp?

2

There are 2 best solutions below

0
Yehor Androsov On

I checked source code of this package and I think a lot of compression benefits gets lost during convertion source image to Bitmap. I tried using Google's tool for converting files to webp and it reduced image file for from 100 KB to 74 KB. You can embed it into your project.

Starting an exe in Web environment can be tricky, but you can check some articles on this topic http://www.codedigest.com/articles/aspnet/334_working_with_exe_in_aspnet-calling_killingaborting_an_exe.aspx

More about cwebp can be found here https://developers.google.com/speed/webp/docs/cwebp

Download link https://developers.google.com/speed/webp/download

using System;
using System.Diagnostics;

namespace ConsoleApp15
{
    class Program
    {
        static void Main(string[] args)
        {
            var filePath = @"C:\Users\jjjjjjjjjjjj\Downloads\libwebp-1.0.3-windows-x86\bin\cwebp.exe";
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = filePath;
            startInfo.Arguments = "file.jpeg -o file.webp";

            startInfo.CreateNoWindow = true; // I've read some articles this is required for launching exe in Web environment
            startInfo.UseShellExecute = false;
            try
            {
                using (Process exeProcess = Process.Start(startInfo))
                {
                    exeProcess.WaitForExit();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
    }
}
0
Celso Jr On

ImageProcessor and ImageProcessor.Plugins.WebP will not work with animated gifs, get rid of that and use ImageMagick.NET instead.

public async Task<IActionResult> Store(IFormFile file)
{
    if (!ModelState.IsValid)
    {
        return Problem("Invalid model!");
    }

    string absoluteFilename = Path.Combine("d:/uploaded_images", Path.GetRandomFileName() + ".webp");

    using FileStream stream = new FileStream(absoluteFilename, FileMode.Create);
    using MagickImageCollection images = new MagickImageCollection(stream);
    foreach (IMagickImage<ushort> image in images)
    {
        image.Quality = 100;
        image.Settings.SetDefines(new WebPWriteDefines() { Lossless = true, Method = 6 });
        image.Settings.Compression = CompressionMethod.WebP;
        image.Format = MagickFormat.WebP;
    }
    images.Write(absoluteFilename, MagickFormat.WebP);

    return Ok(absoluteFilename);
}

Adjust this snippet to your needs.