Исключение нехватки памяти в System.Drawing.Image - PullRequest
0 голосов
/ 12 октября 2018

Мне нужно изменить размер загружаемого файла изображения / изображений в 3 различных размера (каждый из них) и сохранить их пути в базе данных.

Я написал для этого любимый метод.

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>

Использую ли я слишком много памяти?Как я могу это исправить?

1 Ответ

0 голосов
/ 12 октября 2018

слишком много 'path' в вашей процедуре объявить, perharps сокращает его до:

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

Вы только что отредактировали

...