Ive seen lots of tutorials of how to resize an image to some height or width, but none of them explain what to do in case you need to reduce its disk space to a limit of, say, 200Kb. This may not be the best way of dealing with this but it works:
Getting and checking the image
//Lets imagine im uploading an image from a .Net FileUpload object: System.Drawing.Image img = System.Drawing.Image.FromStream(Uploader.PostedFile.InputStream); //Now, I check the size limit: if (ImageSize(img) > 200){ img = ResizeImageTo200K(img); }
Resizing it
I just make a bucle to resize the image until its less than 200k or I may have get into an infinite loop:
private System.Drawing.Image ResizeImageTo200K(System.Drawing.Image img) { int control = 0; while ((ImageSize(img) / 1024) > 200) { double prop = ((ImageSize(img) / 1024) / 200.00) - 1; if (prop > 0.1) { //Very big, lets reduce proporcionally img = resizeImage(img, (int)(img.Width * prop), (int)(img.Height * prop)); } else { // Lets try reducing a 10% img = resizeImage(img, (int)(img.Width * 0.9), (int)(img.Height * 0.9)); } control += 1; if (control > 10) break; //infinite bucle control } return img; }
The rest of functions:
private System.Drawing.Image resizeImage(System.Drawing.Image img, int newWidth, int newHeight){ return new Bitmap(img, newWidth, newHeight); } private int ImageSize(System.Drawing.Image img) { return getImageAsByteArray(img).Length; } private byte[] getImageAsByteArray(System.Drawing.Image img) { MemoryStream ms = new MemoryStream(); img.Save(ms, format); return ms.ToArray(); }
Warning! Little issue
It seems that when I am converting the image to byte array I need its format to do that. Unfortunately when I resize the image I am creating a new object that seems to lose somehow its RawFormat (in fact it doesnt, Ive checked it debugging, but thats the error I get). So to fix this issue Ive declared a variable in the class to save the original format and use it everytime I need to convert to byte array:
// Hack . I need this var to convert Image objects to byte Array. - RC private System.Drawing.Imaging.ImageFormat originalFormat; public void UploadProfileImage(FileUpload Uploader) { ... Image img = System.Drawing.Image.FromStream(Uploader.PostedFile.InputStream); originalFormat = img.RawFormat; ... } private byte[] getImageAsByteArray(System.Drawing.Image img) { MemoryStream ms = new MemoryStream(); img.Save(ms, originalFormat); return ms.ToArray(); }
You may need to include:
using System.Drawing; using System.Drawing.Imaging; using System.IO;