It is very common apps have some image processing. Mobile apps usually apply filters. Web apps can get a file from a upload and store it.
In this operations we could store image in different sizes, keeping desired patterns (of sizes) and optimizing the data traffic.
Because of operations like that, I created a helper to use in some of my projects, let me share it.
using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; namespace PocWpf { public static class ImageHelper { /// <summary> /// Resize image keeping ratio (no distortion) /// </summary> /// <param name="image">image to resize</param> /// <param name="sizeBase"> /// Size base, eg 100px. If width is bigger, 100px will be assumed for width, /// and height will keep the proportion. /// </param> /// <returns>new image with the new size</returns> public static Image ResizeImage(this Image image, int sizeBase) { //get the min ratio var ratioX = (double)sizeBase / image.Width; var ratioY = (double)sizeBase / image.Height; var ratio = Math.Min(ratioX, ratioY); // apply ratio to measurements var newWidth = (int)Math.Ceiling(image.Width * ratio); var newHeight = (int)Math.Ceiling(image.Height * ratio); // build a bitmap with the new sizes var newImage = new Bitmap(newWidth, newHeight); // paint image into the bitmap Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight); return newImage; } /// <summary>convert byte array to image</summary> public static Image ToImage(this byte[] bytes) { using (var ms = new MemoryStream(bytes)) { var image = Image.FromStream(ms); return image; } } /// <summary>convert image to byte array</summary> public static byte[] ToBytes(this Image image) { using (var ms = new MemoryStream()) { image.Save(ms, ImageFormat.Png); var result = ms.ToArray(); return result; } } /// <summary>convert stream to byte array</summary> public static byte[] ToBytes(this Stream stream) { using (var ms = new MemoryStream()) { stream.Position = 0; stream.CopyTo(ms); var result = ms.ToArray(); return result; } } /// <summary>get image from file path and converts to byte array</summary> public static byte[] FileToByteArray(this string fileName) { using (var stream = File.OpenRead(fileName)) { using (var reader = new BinaryReader(stream)) { return reader.ReadBytes((int)stream.Length); } } } /// <summary>resize image from byte array.</summary> public static byte[] ResizeImage(byte[] imageBytes, int sizeBase) { return ResizeImage(imageBytes.ToImage(), sizeBase).ToBytes(); } /// <summary>Get a square of the center of the image </summary> public static Image CropSquare(this Image image, int baseSize) { int newBaseSize; // get a base size based of minimal size if (image.Width > image.Height) newBaseSize = (baseSize * image.Width) / image.Height; else newBaseSize = (baseSize * image.Height) / image.Width; // resize image var resizedImage = image.ResizeImage(newBaseSize); // dispose old image image.Dispose(); // get the square using (var bmpImage = new Bitmap(resizedImage)) { // build the square var rectangle = new Rectangle((resizedImage.Width / 2) - (baseSize / 2), (resizedImage.Height / 2) - (baseSize / 2), baseSize, baseSize); // dispose this image... it won't be used anymore. resizedImage.Dispose(); // paint the image respecting the square. var result = bmpImage.Clone(rectangle, bmpImage.PixelFormat); return result; } } } }
And here I have an WPF example:
using Microsoft.Win32; using System; using System.IO; using System.Windows; using System.Windows.Media.Imaging; namespace PocWpf { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void btnLoad_Click(object sender, RoutedEventArgs e) { var dialog = new OpenFileDialog(); if (dialog.ShowDialog() == true) imgOriginal.Source = new BitmapImage(new Uri(dialog.FileName)); } private void btnResize_Click(object sender, RoutedEventArgs e) { var image = ((BitmapImage)imgOriginal.Source) .UriSource .LocalPath .FileToByteArray() // helper here .ToImage(); // and here imgResized.Source = this.LoadBitmapImageFromImage(image.ResizeImage(100)); // helper here imgCropped.Source = this.LoadBitmapImageFromImage(image.CropSquare(100)); // helper here image.Dispose(); } private BitmapImage LoadBitmapImageFromImage(System.Drawing.Image image) { var result = new BitmapImage(); result.BeginInit(); result.StreamSource = new MemoryStream(image.ToBytes()); // helper here result.EndInit(); return result; } } }
How you could see, I have the possibility to rescale the image and crop a square… there are some helpers to convert image in byte array, stream and that stuff.
Now tell me: do you think that can be useful?
Spaki
7,676 thoughts on “Image Resize with .NET”