首页 > 解决方案 > System.Drawing.Image 中的内存不足异常

问题描述

我需要调整 3 种不同大小(每个)的文件上传图像/图像的大小,并将它们的路径保存到数据库中。

我为此写了 belove 方法。

public void resize(string tempPath,string fname,string extension,int x,int y,string path) {

          System.Drawing.Image img = System.Drawing.Image.FromFile(tempPath);

            using (MemoryStream memory = new MemoryStream())
            {
                Bitmap tnBitmap = new Bitmap(img);
                Graphics tnGraph = Graphics.FromImage(tnBitmap);
                tnGraph.CompositingQuality = CompositingQuality.HighQuality;
                //settings ..
                double ratioX = (double)x / (double)tnBitmap.Width;
                double ratioY = (double)y / (double)tnBitmap.Height;
                double ratio = ratioX < ratioY ? ratioX : ratioY;
                int newHeight = Convert.ToInt32(tnBitmap.Height * ratio);
                int newWidth = Convert.ToInt32(tnBitmap.Width * ratio);    
                int posX = Convert.ToInt32((x - (tnBitmap.Width * ratio)) / 2);
                int posY = Convert.ToInt32((y - (tnBitmap.Height * ratio)) / 2);
                tnGraph.DrawImage(img, posX, posY, newWidth, newHeight);    
                img.Dispose();
                using (FileStream fs = new FileStream(tempPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                {                      
                    tnBitmap.Save(memory, ImageFormat.Jpeg);
                    byte[] bytes = memory.ToArray();
                    fs.Write(bytes, 0, bytes.Length);
                    fs.Close();
                    try
                    {
                        FtpWebRequest req = (FtpWebRequest)WebRequest.Create("ftp://ftp.address.com/httpdocs/img-cdn" + @"\" + fname + extension);    
                        req.UseBinary = true;
                        req.Method = WebRequestMethods.Ftp.UploadFile;
                        req.Credentials = new NetworkCredential("username", "pw");
                        StreamReader rdr = new StreamReader(memory);

                        rdr.Close();
                        req.ContentLength = memory.ToArray().Length;

                        Stream reqStream = req.GetRequestStream();

                        reqStream.Write(memory.ToArray(), 0, memory.ToArray().Length);
                        reqStream.Close();
                    }
                    catch (WebException e)
                    {
                        String status = ((FtpWebResponse)e.Response).StatusDescription;
                    }                       
                    path = "www.address.com/" + fname + extension;
                }
                memory.Dispose();
                tnBitmap.Dispose();
                tnGraph.Dispose();    
            }

}

方法调用:

public ActionResult addPathFu(string ID){
     List<ProductImage> lPi = new List<ProductImage>();
     string mTempPath = Path.GetTempFileName();
     string sTempPath = Path.GetTempFileName();
     string bTempPath = Path.GetTempFileName();
     string extension = "";
     for (int i = 0; i < Request.Files.Count; i++)
     {            
          ProductImage pi = new ProductImage();
          //bigPath file 
          var bigFileName = $@"{DateTime.Now.Ticks}-b";
          extension = Path.GetExtension(Request.Files[i].FileName);
          Request.Files[i].SaveAs(bTempPath);              
          resize(bTempPath,bigFileName,extension,1500,1500,pi.BigPath);

          //midpath 
          var midFileName = $@"{DateTime.Now.Ticks}-m";
          extension=Path.GetExtension(Request.Files[i].FileName);
          resize(mTempPath, midFileName, extension, 500, 750,pi.MidPath);

          Request.Files[i].SaveAs(mTempPath);

          //smallpath
          var sFileName = $@"{DateTime.Now.Ticks}-s";
          extension = Path.GetExtension(Request.Files[i].FileName);
          Request.Files[i].SaveAs(sTempPath);
          resize(sTempPath, sFileName, extension, 295, 443,pi.SmallPath);

          lPi.Add(pi);
     }
  }

问题是,我第二次在运行时调用这个方法, System.Drawing.Image img = System.Drawing.Image.FromFile(tempPath);语句抛出错误:

内存不足异常。

我处理了所有一次性的东西。我也在 web.config 中启用了:

<runtime>
  <gcAllowVeryLargeObjects enabled="true" />
</runtime>

我是否使用了太多内存?我怎样才能解决这个问题?

标签: c#asp.net-mvcbitmapout-of-memorysystem.drawing

解决方案


您的例程声明中的“路径”太多,可能会缩短它,例如:

public void resize(string tempPath, string fname, string extension, int x, int y, string path, Image img)

你刚刚编辑


推荐阅读