65.9K
CodeProject 正在变化。 阅读更多。
Home

重命名、调整大小、上传图片 (ASP.NET MVC)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (14投票s)

2015年2月1日

CPOL
viewsIcon

115606

downloadIcon

4477

如何在 MVC 中上传、重命名和调整大小

问题

  1. 文件覆盖,如果文件名已存在
  2. 图片调整大小

解决方案

我创建了一个名为“ImageUpload”的类,解决了上述问题。该类将文件名重命名为“item_counter_filename”。如果该名称在目录中已存在,它将递增计数器 1,直到找到可用的名称(这是递归完成的)。之后,该类将根据您的需要调整图片大小。如果您设置了 Width Height,那么您将强制进行非比例调整大小,这可能会导致失真。但是,如果您设置了 Width Height,那么您将按比例调整图片大小。

将完成所有工作的方法称为“RenameUploadFile”。此方法返回一个名为“ImageResult”的 POCO 对象。

    public class ImageResult
    {
        public bool Success { get; set; }
        public string ImageName { get; set; }
        public string ErrorMessage { get; set; }        
    }

如果上传成功,则 Success 属性将被设置为 true。然后您可以保存 ImageName ,其中包含已上传到目录的最终文件名。如果 Success false,则 ErrorMessage 将包含 Exception 消息。

快给我代码吧!

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)
                {
                    // width + height will force size, care for distortion
                    //Exmaple: ImageUpload imageUpload = new ImageUpload { Width = 800, Height = 700 };

                    // height will increase the width proportionally
                    //Example: ImageUpload imageUpload = new ImageUpload { Height= 600 };
                                        
                    // width will increase the height proportionally
                    ImageUpload imageUpload = new ImageUpload { Width= 600 };

                    // rename, resize, and upload
                    //return object that contains {bool Success,string ErrorMessage,string ImageName}
                    ImageResult imageResult = imageUpload.RenameUploadFile(file);
                    if (imageResult.Success)
                    {
                        //TODO: write the filename to the db
                        Console.WriteLine(imageResult.ImageName);
                    }
                    else
                    {
                        // use imageResult.ErrorMessage to show the error
                        ViewBag.Error = imageResult.ErrorMessage;
                    }
                }
            }

          return View();
        }

ImageUpload.cs

public class ImageUpload
    {
        // set default size here
        public int Width { get; set; }
        
        public int Height { get; set; }

        // folder for the upload, you can put this in the web.config
        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)))
            {
                //file exists => add country try again
                return RenameUploadFile(file, ++counter);
            }
            //file doesn't exist, upload item but validate first
            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);

            //make sure the file is valid
            if (!ValidateExtension(extension))
            {
                imageResult.Success = false;
                imageResult.ErrorMessage = "Invalid Extension";
                return imageResult;
            }

            try
            {
                file.SaveAs(path);

                Image imgOriginal = Image.FromFile(path);

                //pass in whatever value you want
                Image imgActual = Scale(imgOriginal);
                imgOriginal.Dispose();
                imgActual.Save(path);
                imgActual.Dispose();
                
                imageResult.ImageName = fileName;

                return imageResult;
            }
            catch (Exception ex)
            {
                // you might NOT want to show the exception error for the user
                // this is generally logging or testing

                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;

           // force resize, might distort image
            if (Width != 0 && Height != 0)
            {
                destWidth = Width;
                destHeight = Height;
            }
            // change size proportially depending on width or 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; }      
    }
© . All rights reserved.