Resize
takes a byte[], and ints for width/height. returns a byte[] for the new image. keeps a static copy of previously provided sizes to reduce GC activity.
Source
private static readonly IList<Tuple<Rectangle, Image>> BitmapSizes = new List<Tuple<Rectangle, Image>>();
//adapted from http://www.webcosmoforums.com/asp/321-create-high-quality-thumbnail-resize-image-dynamically-asp-net-c-code.html
//TODO: figure out how expensive this method is
//TODO: see if there's a way to make the IDisposable objects static
//TODO: make sure caching is set up properly to reduce usage
public static byte[] Resize(this byte[] source, int width, int height) {
try {
using (var image = Image.FromStream(new MemoryStream(source), true, true)) {
var srcWidth = image.PhysicalDimension.Width;
var srcHeight = image.PhysicalDimension.Height;
if (srcWidth == width && srcHeight == height)
return source;
var scaleW = (double)width / srcWidth;
var scaleH = (double)height / srcHeight;
if (scaleW < scaleH) {
width = (int)Math.Round((scaleW * srcWidth));
height = (int)Math.Round((scaleW * srcHeight));
} else {
width = (int)Math.Round((scaleH * srcWidth));
height = (int)Math.Round((scaleH * srcHeight));
}
var bmpTouple = BitmapSizes.FirstOrDefault(t => t.Item1.Height == height && t.Item1.Width == width);
if (bmpTouple == null) {
bmpTouple = new Tuple<Rectangle, Image>(
new Rectangle(0, 0, width, height),
new Bitmap(width, height));
BitmapSizes.Add(bmpTouple);
}
var rect = bmpTouple.Item1;
var bmp = bmpTouple.Item2;
using (Graphics gr = Graphics.FromImage(bmp)) {
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
gr.DrawImage(image, rect);
using (var outStream = new MemoryStream()) {
bmp.Save(outStream, ImageFormat.Jpeg);
return outStream.ToArray();
}
}
}
} catch (Exception ex) {
throw;
}
return null;
}
Example
public byte[] ImageResult(byte[] imageData, int width, int height) {
return imageData.Resize(width, height);
}