2010-06-20 30 views
2

我一直在处理图像gallary。当用户上传图片时,我现在检查文件的大小。如果它小于1MB,我检查该文件实际上是一种图像类型。最后,我将图像大小调整为合适的大小,并创建图像的小缩略图。不过,由于在代码中添加了检查我已经尝试过的类型和OutOfMemoryException。OutOfMemoryException C#上传图像文件

这里是我的控制器的方法:

 [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Upload(Image image, HttpPostedFileBase ImageFile) 
    { 

     if (ImageFile.ContentLength > 0) 
     { 
      // Get the size in bytes of the file to upload. 
      int fileSize = ImageFile.ContentLength; 

      // Allow only files less than 1,048,576 bytes (approximately 1 MB) to be uploaded. 
      if (fileSize < 1048576) 
      { 
       string fileclass = ""; 

       using (BinaryReader r = new BinaryReader(ImageFile.InputStream)) 
       { 
        byte buffer = r.ReadByte(); 
        fileclass = buffer.ToString(); 
        buffer = r.ReadByte(); 
        fileclass += buffer.ToString(); 
        r.Close(); 
       } 

       switch (fileclass) 
       { 
        case "7137": 
        case "255216": 
        case "13780": 
         try 
         { 
          string path = Server.MapPath("~/Uploads/"); 

          ImageFile.SaveAs(path + ImageFile.FileName); 

          ResizeImageHelper resizeImageHelper = new ResizeImageHelper(); 
          resizeImageHelper.ResizeImage(path + ImageFile.FileName, path + ImageFile.FileName, 640, 480, false); 
          resizeImageHelper.ResizeImage(path + ImageFile.FileName, path + "thumb" + ImageFile.FileName, 74, 74, false); 

          image.imageLocation = ImageFile.FileName; 
          image.imageThumb = "thumb" + ImageFile.FileName; 

          imageRepository.Add(image); 
          imageRepository.Save(); 

          return RedirectToAction("Index", "Home"); 
         } 
         catch (Exception ex) 
         { 
          return View("Error"); 
         } 
       } 

      } 
      else 
      { 
       //If file over 1MB 
       return View("Error"); 
      } 
     } 
     else 
     { 
      //If file not uploaded 
      return View("Error"); 
     } 

     return View("Error"); 
    } 

这里是调整大小的方法我用:

public void ResizeImage(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider) 
    { 
     System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile); 

     // Prevent using images internal thumbnail 
     FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); 
     FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); 

     if (OnlyResizeIfWider) 
     { 
      if (FullsizeImage.Width <= NewWidth) 
      { 
       NewWidth = FullsizeImage.Width; 
      } 
     } 

     int NewHeight = FullsizeImage.Height * NewWidth/FullsizeImage.Width; 
     if (NewHeight > MaxHeight) 
     { 
      // Resize with height instead 
      NewWidth = FullsizeImage.Width * MaxHeight/FullsizeImage.Height; 
      NewHeight = MaxHeight; 
     } 

     System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero); 

     // Clear handle to original file so that we can overwrite it if necessary 
     FullsizeImage.Dispose(); 

     // Save resized picture 
     NewImage.Save(NewFile); 
    } 

任何人都可以建议本?我目前只是在玩周围试图学习新的东西:-)

感谢,

乔恩

进展我已经把范围缩小到该块,当注释掉的东西作为普通:

using (BinaryReader r = new BinaryReader(ImageFile.InputStream)) 
       { 
        byte buffer = r.ReadByte(); 
        fileclass = buffer.ToString(); 
        buffer = r.ReadByte(); 
        fileclass += buffer.ToString(); 
        r.Close(); 

       } 
+0

异常发生在哪里? – 2010-06-20 23:17:04

+0

我刚刚发现它出现在这一行:System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile); – 2010-06-20 23:18:23

+0

但是,在我开始将所有检查都到位之前,这是工作的。 – 2010-06-20 23:18:41

回答

2

我假设这不会发生首次运行,但一段时间后。它是否正确?

编辑删除不正确的假设,但仍然有IDisposable


你不是处置NewImage的问题,这将导致在生产中的问题。

我通常说'只是使用',但尝试/最后是同样的事情。重新给我们一个使用自己的判断。

System.Drawing.Image NewImage = null; 
System.Drawing.Image FullsizeImage = null; 

try 
{ 
    FullsizeImage = System.Drawing.Image.FromFile(OriginalFile); 

    [... snip ... ] 

    NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero); 

    // Clear handle to original file so that we can overwrite it if necessary 
    FullsizeImage.Dispose(); 

    // Save resized picture 
    NewImage.Save(NewFile); 
} 
finally 
{ 
    if (FullsizeImage != null) 
     FullsizeImage.Dispose(); 
    if (NewImage != null) 
     NewImage.Dispose(); 
} 
+0

第一次运行时不会发生这种情况。研究这一行的逻辑ImageFile.SaveAs(path + ImageFile.FileName);该文件不能正确保存在文件夹中。它显示为0个字节。 – 2010-06-20 23:22:35

+1

我明白了。那么你的图像调整大小代码仍然缺少它'IDisposable.Dispose'调用。我将留下这个答案作为对此的评论。 – 2010-06-20 23:30:11

+0

对于任何IDisposable对象,您应该确实习惯使用对象来处理.Dispose()调用。 使用(图片newImage = FullSizeImage.GetThumbnailImage(newWidth,newHeight,空,IntPtr.Zero){ // 做的东西与newImage } //结束范围自动销毁对象 – Michael 2010-06-21 06:08:36

0

玉家伙后,发现了这部分代码是问题:

using (BinaryReader r = new BinaryReader(ImageFile.InputStream)) 
      { 
       byte buffer = r.ReadByte(); 
       fileclass = buffer.ToString(); 
       buffer = r.ReadByte(); 
       fileclass += buffer.ToString(); 
       r.Close(); 

      } 

我改成了这样:

string fileclass = ImageFile.ContentType.ToString(); 

并改变了我的switch语句:

switch (fileclass) 
       { 
        case "image/jpg": 
        case "image/jpeg": 
        case "image/png": 
        case "image/gif": 
         try 

我也执行了罗伯特的建议。不过,我不确定.NET是否是新的,这种检查文件类型的方法是否与以前一样精确?我的研究似乎表明,即使上载器已经改变了扩展名,例如上一个可能发现文件类型。将example.exe重命名为example.jpg。我不确定使用提供的.NET功能是否仍然可以实现?

+0

我记不起手,但是请求的ContentType可以由执行上传的客户端设置,如果是这样的话,被恶意客户端欺骗,文件扩展名也是如此。可能不想完全信任它们,也可以检查System.Drawing.Image的实例属性RawFormat的类型为System.Drawing.Imaging.ImageFor mat'并将其与静态实例进行比较。例如。 'if(uploadedImage.RawFormat == ImageFormat.Jpeg)...' – 2010-06-21 05:33:54