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; } } }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With