c# - 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>
我是否使用了太多内存?我怎样才能解决这个问题?
解决方案
您的例程声明中的“路径”太多,可能会缩短它,例如:
public void resize(string tempPath, string fname, string extension, int x, int y, string path, Image img)
你刚刚编辑
推荐阅读
- windows-10 - 双击选择不考虑 - 作为 Windows 10 for onenote 中的一个词
- vue.js - 从本地文件导入 Vue 中的插件
- python - 如何在 Tkinter 中将事件绑定到鼠标滚轮单击(而不是滚动)?
- php - 通过 PHP 访问 Youtube 的 Google API 密钥
- java - 从哪里加载应用程序内容
- php - SELECT * FROM table WHERE value IN array 只返回一个结果
- reactjs - 使用 React 中的调度将数组中的项目替换为新值
- f# - 如何让 SQLProvider 使用 Npgsql 在单声道上工作?
- vba - 如何使用户窗体在 Microsoft Word 中按需显示?
- java - 在JAVA中的特定位置写入JSON文件