The Problem
- File overwrite, if filename already exists
- Image Resizing
The Solution
I created a Class called "ImageUpload
" that solves the above problems. The Class renames the filename with "item_counter_filename
". If the name already exists in the directory, it will increment the counter by 1
until an available name is found (this is done recursively). Afterwards, the Class will resize the image to your needs. If you set the Width
and Height
, then you will be forcing a non proportional resize, this might cause distortion. However, if you set the Width
or Height
, then you will be resizing the image proportionally.
The method that will do all the work is called "RenameUploadFile
". This method returns a POCO object called "ImageResult
".
public class ImageResult
{
public bool Success { get; set; }
public string ImageName { get; set; }
public string ErrorMessage { get; set; }
}
If the upload was successful, then the Success
property will be set to true
. Then you can save ImageName
which holds the final filename that has been uploaded to the directory. If Success
was false
, ErrorMessage
will contain the Exception
message.
Show Me the Code Already!
Index.cshtml
<div class="row">
<div class="col-md-12">
<h2>Rename, Resize, and Upload Image</h2>
@if (ViewBag.Error != null)
{
<h4 style="color:red">@ViewBag.Error</h4>
}
@using (Html.BeginForm("Index", "Home",
FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>Upload Image</div>
<input type="file" name="avatar" />
<input type="submit" value="upload" />
}
</div>
</div>
HomeController.cs
[HttpPost]
public ActionResult Index(FormCollection formCollection)
{
foreach (string item in Request.Files)
{
HttpPostedFileBase file = Request.Files[item] as HttpPostedFileBase;
if (file.ContentLength == 0)
continue;
if (file.ContentLength > 0)
{
ImageUpload imageUpload = new ImageUpload { Width= 600 };
ImageResult imageResult = imageUpload.RenameUploadFile(file);
if (imageResult.Success)
{
Console.WriteLine(imageResult.ImageName);
}
else
{
ViewBag.Error = imageResult.ErrorMessage;
}
}
}
return View();
}
ImageUpload.cs
public class ImageUpload
{
public int Width { get; set; }
public int Height { get; set; }
private readonly string UploadPath = "~/Images/Items/";
public ImageResult RenameUploadFile(HttpPostedFileBase file, Int32 counter = 0)
{
var fileName = Path.GetFileName(file.FileName);
string prepend = "item_";
string finalFileName = prepend + ((counter).ToString()) + "_" + fileName;
if (System.IO.File.Exists
(HttpContext.Current.Request.MapPath(UploadPath + finalFileName)))
{
return RenameUploadFile(file, ++counter);
}
return UploadFile(file, finalFileName);
}
private ImageResult UploadFile(HttpPostedFileBase file, string fileName)
{
ImageResult imageResult = new ImageResult { Success = true, ErrorMessage = null };
var path =
Path.Combine(HttpContext.Current.Request.MapPath(UploadPath), fileName);
string extension = Path.GetExtension(file.FileName);
if (!ValidateExtension(extension))
{
imageResult.Success = false;
imageResult.ErrorMessage = "Invalid Extension";
return imageResult;
}
try
{
file.SaveAs(path);
Image imgOriginal = Image.FromFile(path);
Image imgActual = Scale(imgOriginal);
imgOriginal.Dispose();
imgActual.Save(path);
imgActual.Dispose();
imageResult.ImageName = fileName;
return imageResult;
}
catch (Exception ex)
{
imageResult.Success = false;
imageResult.ErrorMessage = ex.Message;
return imageResult;
}
}
private bool ValidateExtension(string extension)
{
extension = extension.ToLower();
switch (extension)
{
case ".jpg":
return true;
case ".png":
return true;
case ".gif":
return true;
case ".jpeg":
return true;
default:
return false;
}
}
private Image Scale(Image imgPhoto)
{
float sourceWidth = imgPhoto.Width;
float sourceHeight = imgPhoto.Height;
float destHeight = 0;
float destWidth = 0;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
if (Width != 0 && Height != 0)
{
destWidth = Width;
destHeight = Height;
}
else if (Height != 0)
{
destWidth = (float)(Height * sourceWidth) / sourceHeight;
destHeight = Height;
}
else
{
destWidth = Width;
destHeight = (float)(sourceHeight * Width / sourceWidth);
}
Bitmap bmPhoto = new Bitmap((int)destWidth, (int)destHeight,
PixelFormat.Format32bppPArgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, (int)destWidth, (int)destHeight),
new Rectangle(sourceX, sourceY, (int)sourceWidth, (int)sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
}
ImageResult.cs
public class ImageResult
{
public bool Success { get; set; }
public string ImageName { get; set; }
public string ErrorMessage { get; set; }
}