C# WinForm 循环加载图片出现内存不足

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# WinForm 循环加载图片出现内存不足相关的知识,希望对你有一定的参考价值。

用了一个 listBox1控件加载了某目录下50张图片的文件路径信息。

private void button1_Click(object sender, EventArgs e)

int i=1;

foreach (string s in listBox1.Items)

Image img = new Bitmap(Image.FromFile(s)); //这个地方一般历遍到第27张就出现内存不足。
i = i++ ;
MessageBox.Show(i.ToString()); // 历遍到27

img.Dispos



说明:只做了加载后,就立即释放资源,这个循环也会出错。更用不说对img做什么处理了。 Image img = new Bitmap(Image.FromFile(s)); 历遍到第27张就出现内存不足。
在操作系统任务管理器的进程里看到历遍一个就增加一下内存。增到1,417,916K左右就出现内存不足。img.Dispos并不能及时释放资源。

高手门,有什么方法可以及时释放资源的?指点下啊!感激不尽!

首先i=i++;就是不对的。
再者你的图片多大啊,27张就用了1.5g的内存。追问

i=i++; 这个地方是次要的,只是为了记录历遍了多少次。
每张图片有4M左右。都是用专业相机照的相片,50张是用来测试的了,我的服务器有上差不多一万张。对存储需求非上大。所以要写个程序去批量缩小图片象素。不需要这么专业高清的图片,单张的图片我实现了。但批量的处理时就不行了,提示内存不足。后来我一步步排除。发现单单就是历编加载图片,然后立即释放资源都提示内存不足。

追答

你可以看看这部分代码,对比一下哪里不对。
Bitmap bt = new Bitmap(120, 120); //创建Bitmap实例
Graphics g = Graphics.FromImage(bt); //创建Graphics实例
g.Clear(Color.White); //设置画布背景颜色为白色
Image ReducedImage; //缩略图
Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);
ImageWidth = Convert.ToInt32(ResourceImage.Width * Percent); //设置宽度
ImageHeight = Convert.ToInt32(ResourceImage.Height * Percent); //设置高度
//获取所谓图
ReducedImage = ResourceImage.GetThumbnailImage(ImageWidth, ImageHeight, callb, IntPtr.Zero);
if (ImageWidth > ImageHeight) //如果原图宽度大于高度

//缩放图片
g.DrawImage(ReducedImage, 0, (int)(120 - ImageHeight) / 2, ImageWidth, ImageHeight);

else

g.DrawImage(ReducedImage, (int)(120 - ImageWidth) / 2, 0, ImageWidth, ImageHeight);

g.DrawRectangle(new Pen(Color.Gray), 0, 0, 119, 119); //绘制缩略图的边框
bt.Save(@targetFilePath, ImageFormat.Jpeg); //保存缩略图
bt.Dispose(); //释放对象
ReducedImage.Dispose(); //释放对象
return true;

追问

谢谢!找到原因了。总结一下给大伙们参考参考。在微软官网上看到段解释。Bitmap 一个 图像对象从一个文件构造时该文件仍保留锁定对象的生存期。所以关键是要使用 Graphics.DrawImage() 方法来将映像复制到新位图对象。然后Bitmap和Graphics就可以释放了。然后用新位图进行缩减像素处理,保存后再释放。我新建一个线程来历遍处理较果比较好。我批量处理了12660张图片。程序的运行内存都只是在2M至8M间跳动。

参考技术A 你好LZ 我也要弄一个类似的功能 你的程序能分享下么 邮箱 bdf216@163.com 十分感谢 参考技术B 那用gc.Collect()回收一下看看。
你再注意下这行代码:
Image img = new Bitmap(Image.FromFile(s));

换成Bitmap bmp = new Bitmap(s);
估计就没问题了。追问

感谢:youngking87 换成Bitmap bmp = new Bitmap(s);是可以历遍完 listBox1.Items 。
但我需要将Bitmap 转换成Image
用 Image img = Image .GetThumbnailImage(x, y, null, new IntPtr());这样缩小图片
历编第一个转换就出现内存不足了。 我在后面加上 gc.Collect(); 也没用。因为在历遍中第一个转换就提示内存不足了。我的历编是加一个,就转换一个,然后再释放一个。这样循环历遍的。

追答

嗯,可以啊。那下面再释放img。就好了。

本回答被提问者采纳

求教:C#中winform 并未使用任何图片,但报错”GDI+ 中发生一般性错误“

我程序中使用了一个dll控件,当程序登录的时候这个控件会显示出“进度条”。
我在主程序中添加了这个dll控件,加了个菜单menuStrip1,菜单中加了一个 “文件”--“登录”,框,当点击登录就弹出个“登录窗口”,登录后回到主程序。
这时dll控件进度条正常,但是每当我鼠标 移动到 菜单menuStrip1 上,马上就会报错“GDI+ 中发生一般性错误”。事实上,我程序中没有任何画图、加载图片的代码。(也许是dll中使用了,但dll不是我做的...)
当我鼠标不靠近menuStrip1 时,一切又正常。

这种情况我感觉有点像是多线程问题?当登录后dll控件运行正常,但是menuStrip1 上会失去响应,当鼠标移到上面就报错。如图

求教各位高手,怎么解决,上网去查几乎统统是说和图片有关......

谢谢!!!!!!!!!!!!

在构造函数里面设置一下这个属性试一下
Control.CheckForIllegalCrossThreadCalls = false;
参考技术A 是不是图片被转码过了 转换成 byte格式了来自:求助得到的回答 参考技术A 加载完将控件释放试一试

以上是关于C# WinForm 循环加载图片出现内存不足的主要内容,如果未能解决你的问题,请参考以下文章

c# winform 资源图片如何通过字符串拼凑的形式加载?

VS 2008 (C#) 使用Winform方式,控件Listview要等数据全部加载完后才显示,有啥办法边加载边显示?

winform怎么一边加载一边gif动图

C# winform中使用动态加载控件的属性

在winform上添加用户控件过多时出现闪烁

关于c# winform 编程的,怎么弄提示类似“加载中”的小窗口