PixelPaul
PixelPaul

Reputation: 2777

.NET ImageSharp Crop and Resize throws error

I'm converting some older code to .NET 8 and using the ImageSharp (3.1.4) library. It is processing an uploaded image, centers it,crops it, resizes it and saves the file.

Here is my code:

public void ResizeCropAndSaveImage(IFormFile file, int cropWidth, int cropHeight, string filePath, string fileName)
{
    using (Image image = Image.Load(file.OpenReadStream()))
    {
        // get the shorter side & scale percentages
        var ratio = Math.Min((float)image.Width / cropWidth, (float)image.Height / cropHeight);
        var scaleH = Convert.ToInt32(cropHeight * ratio);
        var scaleW = Convert.ToInt32(cropWidth * ratio);

        // set crop from center coordinates
        var posX = (image.Width - scaleW) / 2;
        var posY = (image.Height - scaleH) / 2;

        var resizedImage = image.Clone(i => i.Resize(cropWidth, cropHeight).Crop(new Rectangle(posX, posY, scaleW, scaleH)));

        Directory.CreateDirectory(filePath);
        resizedImage.Save(Path.Combine(filePath, fileName), new JpegEncoder());
    }
}

But it's throwing the following error:

System.ArgumentException: Crop rectangle should be smaller than the source bounds. (Parameter 'cropRectangle')

The error seems self explanatory, but the new Rectangle() is smaller than the source images so I'm not sure what's happening?

Upvotes: 1

Views: 197

Answers (1)

Abolfazl Moslemian
Abolfazl Moslemian

Reputation: 173

The issue is happening because you're resizing the image before cropping, which can lead to invalid crop dimensions. You should crop the image first, then resize it. Here's how you can fix it:

  1. Crop the image to the right size from the center
  2. Resize the cropped image
  3. Save the resized image
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;
using System;
using System.IO;

public void ResizeCropAndSaveImage(IFormFile file, int cropWidth, int cropHeight, string filePath, string fileName)
{
    using (Image image = Image.Load(file.OpenReadStream()))
    {
        //get the shorter side & scale percentages
        var ratio = Math.Min((float)image.Width / cropWidth, (float)image.Height / cropHeight);
        var scaledH = (int)(cropHeight * ratio);
        var scaledW= (int)(cropWidth * ratio);

        // Set crop from center coordinates
        var posX = (image.Width - scaledWidth) / 2;
        var posY = (image.Height - scaledHeight) / 2;

        // Crop the image first
        image.Mutate(i => i.Crop(new Rectangle(posX, posY, scaledWidth, scaledHeight)));

        // Resize the cropped image
        image.Mutate(i => i.Resize(cropWidth, cropHeight));

        Directory.CreateDirectory(filePath);
        image.Save(Path.Combine(filePath, fileName), new JpegEncoder());
    }
}

Upvotes: 1

Related Questions