5

I need to crop images in .NET Core. I used ImageSharp, CoreCompat, and Microsoft.Windows.Compatibility, and scanned all methods I could find. However, I'm still unable to find a method to crop my images. Resizing is there, but not cropping.

How can I crop images in .NET Core based on the upper-left corner's pixel location, width, and height?

Lucas Prestes
  • 362
  • 1
  • 4
  • 19
  • [This](https://gist.github.com/lruckman/fefbe4c02c6e8e1d7d68a18dc1128814) might help for ImageSharp. – Kirk Larkin Aug 21 '18 at 20:20
  • Microsoft documented all approaches you can try, https://blogs.msdn.microsoft.com/dotnet/2017/01/19/net-core-image-processing/ and there can be even more. – Lex Li Aug 22 '18 at 00:16
  • @LexLi, where on that page cropping is mentioned? I don't mean scaling or creating thumbnails. I mean getting the apple image from an apple in the car for example. – mohammad rostami siahgeli Aug 22 '18 at 05:50

5 Answers5

2

I'd suggest using either ImageSharp or CoreCompat.System.Drawing If you're using ImageSharp, I think this is the proper way to crop an image; using ImageProcessors through the Mutate() method:

int width = 0;
int height = 0;
image.Mutate(ctx => ctx.Crop(width, height));

You would need the following namespace to access this:

using SixLabors.ImageSharp.Processing;
  • 1
    Use System.Drawing.Common instead if you're planning on using CoreCompat.System.Drawing. It ships as part of .NET Core and provides the same functionality, but is better maintained. – Frederik Carlier Sep 28 '18 at 10:12
  • `using SixLabors.ImageSharp.Advanced;` No you don't. You need `SixLabors.ImageSharp.Processing` – James South Oct 08 '18 at 14:24
1

You can use ImageSharp library. It has method that crop image based on the upper-left corner. Look at the example below:

private async static Task CropImage()
{
    using (var httpClient = new HttpClient())
    {
        var response = await httpClient.GetAsync("https://assets-cdn.github.com/images/modules/logos_page/GitHub-Mark.png")
            .ConfigureAwait(false);

        using (var inputStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
        {
            using (var image = Image.Load(inputStream))
            {
                var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "foo.png");

                image.Clone(
                    ctx => ctx.Crop(560, 300)).Save(path);
            }
        }
    }
}
kml
  • 280
  • 1
  • 2
  • 9
1

Just install the following package:

System.Drawing.Common package

and use the following code:

using SD = System.Drawing;

static byte[] Crop(string Img, int Width, int Height, int X, int Y)
{
    try
    {
        using (SD.Image OriginalImage = SD.Image.FromFile(Img))
        {
            using (SD.Bitmap bmp = new SD.Bitmap(Width, Height))
            {
                bmp.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution);

                using (SD.Graphics Graphic = SD.Graphics.FromImage(bmp))
                {
                    Graphic.SmoothingMode = SmoothingMode.AntiAlias;

                    Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;

                    Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;

                    Graphic.DrawImage(OriginalImage, new SD.Rectangle(0, 0, Width, Height), X, Y, Width, Height, SD.GraphicsUnit.Pixel);

                    MemoryStream ms = new MemoryStream();

                    bmp.Save(ms, OriginalImage.RawFormat);

                    return ms.GetBuffer();

                }
            }
        }
    }
    catch (Exception Ex)
    {
        throw (Ex);
    }
}

This answer is based on a great article here. However, with the modification to work under .net Core 2.x and above by just installing the mentioned package. By the way, other famous packages are using the same core libraries.

As you can see, you have more flexibility in cropping than the famous libraries mentioned in other answers.

Ciarán Bruen
  • 5,221
  • 13
  • 59
  • 69
Shadi Alnamrouti
  • 11,796
  • 4
  • 56
  • 54
  • More flexibility? Don't spread FUD. Also don't use `ms.GetBuffer()` that can be a byte array larger than the written pixel data – James South May 03 '19 at 15:02
  • Regarding FUD three years later: https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only – Marc Wittke Mar 03 '23 at 16:02
0

First install the package "System.Drawing.Common".

using System.Drawing;
using System.Drawing.Imaging;

...

public byte[] Crop(string path, int width, int height)
{
    Image img = Image.FromFile(path);
    Bitmap bmp = new Bitmap(width, height);
    bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution);
    Graphics g = Graphics.FromImage(bmp);
    g.DrawImage(img, 0, 0);
    using (MemoryStream ms = new MemoryStream())
    {
        bmp.Save(ms, ImageFormat.Jpeg);
        return ms.ToArray();
    }
}
KodFun
  • 323
  • 3
  • 8
0

You can use Bitmap.Clone(Rectangle rect, PixelFormat format), for example, as a Bitmap extension:

using System.Drawing;

static public class BitmapExtensions
{
    static public Bitmap Crop(this Bitmap bitmap, Rectangle rect)
    {
        return bitmap.Clone(rect, bitmap.PixelFormat);
    }
}
Alvaroma
  • 101
  • 4