Lot of sites (specialy in the web 2.0 times) allows the user to upload images to the site. To save disk space and for visual design reasons, it is better to have the images is small size and
specified dimensions. This can be made in two ways. One way is to tell the users to resize the images before uploading them, and the more 'User friendly' way is to let the user upload images with any size and dimensios, and resize them while the uploading.
Here is the code how can it be done:
First we define enum with the resize options:
public enum ResizeOptions
{
// Use fixed width & height without keeping the proportions
ExactWidthAndHeight,
// Use maximum width (as defined) and keeping the proportions
MaxWidth,
// Use maximum height (as defined) and keeping the proportions
MaxHeight,
// Use maximum width or height (the biggest) and keeping the proportions
MaxWidthAndHeight
}
Second, the 'resize' method:
public static System.Drawing.Bitmap DoResize(System.Drawing.Bitmap originalImg, int widthInPixels, int heightInPixels)
{
System.Drawing.Bitmap bitmap;
try
{
bitmap = new System.Drawing.Bitmap(widthInPixels, heightInPixels);
using (System.Drawing.Graphics graphic = System.Drawing.Graphics.FromImage(bitmap))
{
// Quality properties
graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphic.DrawImage(originalImg, 0, 0, widthInPixels, heightInPixels);
return bitmap;
}
}
finally
{
if (originalImg != null)
{
originalImg.Dispose();
}
}
}
Third, the method that calculate the dimensions according to the enum value that passed:
public static System.Drawing.Bitmap ResizeImage(System.Drawing.Bitmap image, int width, int height, ResizeOptions resizeOptions)
{
float f_width;
float f_height;
float dim;
switch (resizeOptions)
{
case ResizeOptions.ExactWidthAndHeight:
return DoResize(image, width, height);
case ResizeOptions.MaxHeight:
f_width = image.Width;
f_height = image.Height;
if (f_height <= height)
return DoResize(image, (int)f_width, (int)f_height);
dim = f_width / f_height;
width = (int)((float)(height) * dim);
return DoResize(image, width, height);
case ResizeOptions.MaxWidth:
f_width = image.Width;
f_height = image.Height;
if (f_width <= width)
return DoResize(image, (int)f_width, (int)f_height);
dim = f_width / f_height;
height = (int)((float)(width) / dim);
return DoResize(image, width, height);
case ResizeOptions.MaxWidthAndHeight:
int tmpHeight = height;
int tmpWidth = width;
f_width = image.Width;
f_height = image.Height;
if (f_width <= width && f_height <= height)
return DoResize(image, (int)f_width, (int)f_height);
dim = f_width / f_height;
// Check if the width is ok
if (f_width < width)
width = (int)f_width;
height = (int)((float)(width) / dim);
// The width is too width
if (height > tmpHeight)
{
if (f_height < tmpHeight)
height = (int)f_height;
else
height = tmpHeight;
width = (int)((float)(height) * dim);
}
return DoResize(image, width, height);
default:
return image;
}
}
Last thing is to connect it all to the uploading event: (Our uploading control called 'fuPhoto' (Normal 'FileUpload' control))
public bool UploadFile()
{
// Make some validatins check (control have file or extension check...)
int width = 300;
int height = 300;
// Do the resize, and save the file with desired name
using( System.Drawing.Bitmap img = ResizeImage(new System.Drawing.Bitmap(fuPhoto.PostedFile.InputStream), width, height, ResizeOptions.MaxWidthAndHeight))
{
string destination = Server.MapPath("~") + Path.GetFileName(FileUpload1.FileName);
switch (Path.GetExtension(fuPhoto.FileName).ToLower())
{
case ".gif":
img.Save(destination, System.Drawing.Imaging.ImageFormat.Gif);
break;
case ".jpg":
default:
img.Save(destination, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
}
}
}
Update:
Some readers asked my about how can this code be used to resize the uploaded image and than save it in to the DB and not to the disk. To save the image to the DB we need to convert it into byte[] (That is how it needs to be sent to the Store Procedre). This can be done in some way. one way is:
public static byte[] ImageToArray(Bitmap image, ImageFormat format)
{
using(MemoryStream mem = new MemoryStream())
{
mem.Position = 0;
image.Save(mem, format);
return mem.ToArray();
}
}
Upload the file using the method 'ResizeImage', than convert the returned Bitmap into byte[] using this method, and send it to your Store Procedure.
done