user12310517
user12310517

Reputation:

How to convert JPEG to WebP format using .NET Core?

I have an ASP.NET Core 3.1 WebAPI that is responsible for providing other apps I have with images. I am trying to improve the performance of my apps. One of the feedback I get from running PageSpeed Insights test is to Serve images in next-gen formats.

All of the images that my WebAPI server are in JPEG format. I don't know much about image compression or image-formats, but I would like to evaluate the results from converting JPEG images to WebP as study show that WebP leads to better results.

I use the following ImageProcessor class to save uploaded images to my WebAPI.

public class ImageProcessor
{
    public Image GetResizedImage(Stream stream, int newWidth, out ImageFormat imageFormat)
    {
        Image sourceImage = Image.FromStream(stream);
        SizeF thumbSize = GetNewSize(sourceImage, newWidth);

        imageFormat = sourceImage.RawFormat;
        return ResizeImage(sourceImage, (int)thumbSize.Width, (int)thumbSize.Height);
    }

    protected SizeF GetNewSize(Image img, int newMaxWidth)
    {
        var size = new SizeF
        {
            Width = newMaxWidth,
            Height = (newMaxWidth * img.Height) / img.Width
        };

        return size;
    }

    protected Bitmap ResizeImage(Image image, int width, int height)
    {
        var destRect = new Rectangle(0, 0, width, height);
        var destImage = new Bitmap(width, height);

        var xRes = Math.Max(Math.Min(image.HorizontalResolution, 96), 72);
        var yRes = Math.Max(Math.Min(image.VerticalResolution, 96), 72);

        destImage.SetResolution(xRes, yRes);

        using (Graphics graphics = Graphics.FromImage(destImage))
        {
            graphics.CompositingMode = CompositingMode.SourceCopy;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            using (ImageAttributes wrapMode = new ImageAttributes())
            {
                wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
            }
        }

        return destImage;
    }
}

Here is how I call the ImageProcessor class to store images on disk from the controller

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

    // Process Image
    Image image = GetResizedImage(file.OpenReadStream(), 1024, out ImageFormat imageFormat);
    MemoryStream memoryStream = new MemoryStream();
    image.Save(memoryStream, imageFormat);
    memoryStream.Seek(0, SeekOrigin.Begin);

    // Store it on disk
    string fullPath = "full path to the new image";
    Directory.CreateDirectory(Path.GetDirectoryName(fullPath));

    using FileStream cacheWriter = new FileStream(fullPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write, 4096, true);
    await memoryStream.CopyToAsync(cacheWriter);

    return Ok();
}

Question

How can I store the image in a WebP format using .Net Core?

Upvotes: 2

Views: 6629

Answers (1)

Jordan Cauley
Jordan Cauley

Reputation: 353

If I were you I would look at installing an instance of Thumbor or using Cloudinary to generate your webp files.

Then you can use JS to conditionally load the correct file.

Upvotes: 1

Related Questions