内存不足,咋整啊

leohuang 2006-09-08 05:52:52
有3千多个图片文件,我现在批量把这些图片缩小,生成一个新文件,
大约转到1千左右就出现内存不足的异常,怎么优化一下啊,望高手赐教,多谢

代码如下:

string[] files = System.IO.Directory.GetFiles(@"E:\uploadfile");
System.Drawing.Image img;
LEO.Common.Thumbnail thum = new LEO.Common.Thumbnail();
foreach(string file in files) {
img = thum.GetThumbnail(file,400,400);
img.Dispose();
string fileName = file.Substring(file.LastIndexOf("\\"),file.Length-file.LastIndexOf("\\"));
System.Diagnostics.Debug.WriteLine(fileName);
//img.Save(@"d:\new" + file);
}
...全文
1254 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
huming_h 2006-09-11
  • 打赏
  • 举报
回复
学习
leohuang 2006-09-10
  • 打赏
  • 举报
回复
呵呵,这么捧场,都结贴了还这么多人顶
hawk234 2006-09-10
  • 打赏
  • 举报
回复
ding
abszhanghe 2006-09-10
  • 打赏
  • 举报
回复
逐个生成文件,生成后一定要释放对象。建议写一个函数如:createImg( string file)file为图片路径。最后几行将用完的对象 ,dispose()一下。在用gc里的函数进行一下强制垃圾处理。

调用时:
foreach( string file in files )
{
createImg(file);
}
阿浩No_1 2006-09-10
  • 打赏
  • 举报
回复
学习
dreamw 2006-09-10
  • 打赏
  • 举报
回复
顶,学到东西啦
leohuang 2006-09-09
  • 打赏
  • 举报
回复
原来是图片坏了,在加载图片的时候报错了
System.Drawing.Image img = System.Drawing.Image.FromFile(fileName);

用下面的方式跳过异常可取吗?要怎么跳过异常才更好?
for( int i = 0; i < 1500; i++ )
{
try{
SaveThumnailImage( SOURCE_FILE, string.Format( @"D:\temp\{0}.jpg", i ) );
}
catch{}
}
双子星的雪季 2006-09-09
  • 打赏
  • 举报
回复
千万别再一下子弄怎么多文件了,再大的内存也不够使
Knight94 2006-09-09
  • 打赏
  • 举报
回复
我试了一下没问题,大致如下:
private void SaveThumnailImage( string strSourceFile, string strDesFile )
{
Image img = GetThumbnail(strSourceFile,400,400);
img.Save( strDesFile);
img.Dispose();
}

public Image GetThumbnail(string fileName,int width,int height)
{
Image img = System.Drawing.Image.FromFile(fileName);

Size size = new Size(width,height);

//新建一个bmp图片
Image bitmap = new Bitmap(size.Width,size.Height);
//新建一个画板
Graphics g = Graphics.FromImage(bitmap);
//设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(img, new Rectangle(0, 0, size.Width, size.Height),
new Rectangle(0, 0, img.Width,img.Height),GraphicsUnit.Pixel);

g.Dispose();
img.Dispose();
return bitmap;
}

//Call
const string SOURCE_FILE = @"D:\Test.jpg";
for( int i = 0; i < 1500; i++ )
{
SaveThumnailImage( SOURCE_FILE, string.Format( @"D:\temp\{0}.jpg", i ) );
Thread.Sleep( 10 );
GC.Collect();
}
poopoo3000 2006-09-09
  • 打赏
  • 举报
回复
做一个大循环,一个小循环,分批读入处理。现在这种方式太危险了,就算你现在没有发现问题,以后也会出问题。
yjf_1982 2006-09-09
  • 打赏
  • 举报
回复
方法一:一次转五百;
方法二:加内存;
方法三:在想。
pretty_soft 2006-09-09
  • 打赏
  • 举报
回复
一下子读进来3000多个,内存多大才够啊
分批
leohuang 2006-09-09
  • 打赏
  • 举报
回复
多谢老大回复,GC.Collect()之后还会出现内存不足

LEO.Common.Thumbnail 是我写的自定义类,方法很简单,就是生成缩略图,
代码如下,麻烦老大看怎么优化一下,不胜感激:

public System.Drawing.Image GetThumbnail(string fileName,int width,int height)
{
System.Drawing.Image img;
img = System.Drawing.Image.FromFile(fileName);

Size size = GetSize(width,height,img.Width,img.Height);
//新建一个bmp图片
Image bitmap = new System.Drawing.Bitmap(size.Width,size.Height);
//新建一个画板
Graphics g = System.Drawing.Graphics.FromImage(bitmap);
//设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(img, new Rectangle(0, 0, size.Width, size.Height),
new Rectangle(0, 0, img.Width,img.Height),GraphicsUnit.Pixel);

g.Dispose();
img.Dispose();
return bitmap;
}
Knight94 2006-09-09
  • 打赏
  • 举报
回复
我不太清楚LEO.Common.Thumbnail是什么东西,第三方组件?有可能它有问题。

改进的方法可以如下试试:
LEO.Common.Thumbnail thum = new LEO.Common.Thumbnail();
private void SaveThumnailImage( string strSourceFile, string strDesDir )
{
Image img = thum.GetThumbnail(strSourceFile,400,400);
string fileName = file.Substring(file.LastIndexOf("\\"),file.Length-file.LastIndexOf("\\"));
System.Diagnostics.Debug.WriteLine(fileName);
img.Save( strDesDir + file);
img.Dispose();
}

//Call it
string[] files = System.IO.Directory.GetFiles(@"E:\uploadfile");
foreach(string file in files)
{
SaveThumnailImage( file, @"d:\new" );
//如果还不行的话,这里显式的调用 "GC.Collect()"看看效果
}
leohuang 2006-09-09
  • 打赏
  • 举报
回复
加内存也不是办法啊,我这是512的内存,客户可能都没512,也让人家加内存就不合理了

像这种批量操作就是慢一点,让程序顺利执行完也可以,通过什么方法呢?
cf20060909 2006-09-09
  • 打赏
  • 举报
回复
我是菜鸟
请多多指教
zheng616 2006-09-09
  • 打赏
  • 举报
回复
用异步执行和分块读就可以了..
alanyhjun 2006-09-09
  • 打赏
  • 举报
回复
我是真的晕了
LinZhongBao 2006-09-09
  • 打赏
  • 举报
回复
帮顶
QQ_370566617 2006-09-09
  • 打赏
  • 举报
回复
是啊,大内存用VirtualAlloc吧,忘了那个函数了
加载更多回复(13)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧