在using语句中返回后的位图ArgumentException

时间:2014-11-21 13:08:47

标签: c# bitmap resize using argumentexception

所以我目前正在开发一个工作/工作得非常好的图像缩放器,但有一个例外,当我一次处理过多的图像时,它给了我一个OutOfMemoryException。

因此,为了解决这个问题,我已将方法包装在using语句中,以便正确处理Bitmaps。

但是我注意到如果我在using语句中返回我的Bitmap,我会得到这个" ArgumentException未处理"消息

这是我的ImageResize方法:

 public Bitmap ResizeImage(MemoryStream ms, Size size)
    {
        if (comboBox2.Text == "Pixel")
        {
            using (Bitmap img = new Bitmap(new Bitmap(ms, true), size.Width, size.Height))
            {
                var original = new Bitmap(ms, true);
                Graphics graphic = Graphics.FromImage(img);

                //IRRELEVANT CODE.....

                return img;
            }
        }
        else
        {
            return null;
        }

在这里,当我尝试将图像保存在ImageResize方法之外时:

private void button1_Click(object sender, EventArgs e)
    {
    //IRRELEVANT CODE ...
    img = ResizeImage(memory, new Size(getX(), getY()));
    //IRRELEVANT CODE ...
    img.Save(outputFileName, codec, encoderParams); //<-Exception occurs here
    }

当我删除using语句时,一切都运行得很好,但是我必须使用using块来处理Bitmap,以防止内存泄漏。 此外,当我将图像保存在using语句中时,它也可以正常工作,但在我的情况下,这不是解决方案。

我做错了什么?对我而言,似乎没有正确返回Bitmap。

我感谢任何帮助和提前感谢 Ravand

2 个答案:

答案 0 :(得分:5)

你把你的使用放在了错误的地方。在使用块结束(包括从其返回)之后,布置由块控制的对象。访问配置的位图是一个错误。

你的使用需要在这里:

private void button1_Click(object sender, EventArgs e)
{
    //IRRELEVANT CODE ...
    using(img = ResizeImage(memory, new Size(getX(), getY())))
    {
        //IRRELEVANT CODE ...
       img.Save(outputFileName, codec, encoderParams);
    }
}

答案 1 :(得分:0)

好吧我终于解决了内存泄漏的问题,结果发现我确实正在释放/处理图像,但它没有做得足够快,导致这个outOufMemoryException,因为你正在处理很多非常大的图像其他。我尝试将所有内容都设置为多线程,并且总是在等待WorkingSet变小而没有成功。

原来它比我想的更容易,我所要做的就是在调整大小的方法结束时把它放在:

GC.Collect();
GC.WaitForPendingFinalizers();
System.Threading.Thread.SpinWait(5000);

这似乎有助于调整大小为10-20mb的大尺寸图像以及10000x10000的分辨率。有人可以解释为什么SpinWait会帮助但不能正常线程睡眠?每当我尝试睡觉时,它似乎也会释放记忆。