Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Resize Center and Crop an image with ImageSharp

Tags:

I need to convert some System.Drawing based code to use this .NET Core compatible library:

https://github.com/SixLabors/ImageSharp

The System.Drawing based code below resizes an image and crops of the edges, returning the memory stream to then be saved. Is this possible with the ImageSharp library?

private static Stream Resize(Stream inStream, int newWidth, int newHeight) {     var img = Image.Load(inStream);     if (newWidth != img.Width || newHeight != img.Height)     {         var ratioX = (double)newWidth / img.Width;         var ratioY = (double)newHeight / img.Height;         var ratio = Math.Max(ratioX, ratioY);         var width = (int)(img.Width * ratio);         var height = (int)(img.Height * ratio);          var newImage = new Bitmap(width, height);         Graphics.FromImage(newImage).DrawImage(img, 0, 0, width, height);         img = newImage;          if (img.Width != newWidth || img.Height != newHeight)         {             var startX = (Math.Max(img.Width, newWidth) - Math.Min(img.Width, newWidth)) / 2;             var startY = (Math.Max(img.Height, newHeight) - Math.Min(img.Height, newHeight)) / 2;             img = Crop(img, newWidth, newHeight, startX, startY);         }     }      var ms = new MemoryStream();     img.Save(ms, ImageFormat.Jpeg);     ms.Position = 0;     return ms; }  private static Image Crop(Image image, int newWidth, int newHeight, int startX = 0, int startY = 0) {     if (image.Height < newHeight)         newHeight = image.Height;      if (image.Width < newWidth)         newWidth = image.Width;      using (var bmp = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb))     {         bmp.SetResolution(72, 72);         using (var g = Graphics.FromImage(bmp))         {             g.SmoothingMode = SmoothingMode.AntiAlias;             g.InterpolationMode = InterpolationMode.HighQualityBicubic;             g.PixelOffsetMode = PixelOffsetMode.HighQuality;             g.DrawImage(image, new Rectangle(0, 0, newWidth, newHeight), startX, startY, newWidth, newHeight, GraphicsUnit.Pixel);              var ms = new MemoryStream();             bmp.Save(ms, ImageFormat.Jpeg);             image.Dispose();             var outimage = Image.FromStream(ms);             return outimage;         }     } } 
like image 933
Darren Avatar asked Mar 22 '19 11:03

Darren


1 Answers

Yeah, super easy.

using (var inStream = ...) using (var outStream = new MemoryStream()) using (var image = Image.Load(inStream, out IImageFormat format)) {     image.Mutate(         i => i.Resize(width, height)               .Crop(new Rectangle(x, y, cropWidth, cropHeight)));      image.Save(outStream, format); } 

EDIT If you want to leave the original image untouched you can use the Clone method instead.

using (var inStream = ...) using (var outStream = new MemoryStream()) using (var image = Image.Load(inStream, out IImageFormat format)) {     var clone = image.Clone(                     i => i.Resize(width, height)                           .Crop(new Rectangle(x, y, cropWidth, cropHeight)));      clone.Save(outStream, format); } 

You might even be able to optimize this into a single method call to Resize via the overload that accepts a ResizeOptions instance with `ResizeMode.Crop. That would allow you to resize to a ratio then crop off any excess outside that ratio.

like image 153
James South Avatar answered Sep 23 '22 16:09

James South