Мне нужно изменить размер загружаемого файла изображения / изображений в 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>
Использую ли я слишком много памяти?Как я могу это исправить?