【问题标题】:Bitmap ArgumentException after returning in using statement在 using 语句中返回后的位图 ArgumentException
【发布时间】:2014-11-21 13:08:46
【问题描述】:

所以我目前正在研究一个图像调整器,它工作/工作得很好,但除了当我一次处理太多图像导致程序崩溃时它给了我一个 OutOfMemoryException。

所以为了解决这个问题,我将方法包装在 using 语句中,以便正确处理位图。

但是我注意到,如果我在 using 语句中返回我的位图,我会收到“ArgumentException was unhandled”消息

这是我的 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 语句中时,它也可以正常工作,但这不是我的解决方案。

我做错了什么?对我来说,位图似乎没有正确返回。

感谢任何帮助,并在此先感谢 拉万德

【问题讨论】:

  • 我喜欢//IRRELEVANT CODE ... 的评论。它属于this thread
  • 哈哈哈,如果你喜欢就贴吧:D 但老实说,在这种情况下它是无关紧要的

标签: c# bitmap resize using argumentexception


【解决方案1】:

你把你的使用放在错误的地方。在 using 块结束后(包括从它返回),由该块控制的对象被释放。访问已释放的位图是错误的。

您的 using 需要在这里:

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);
    }
}

【讨论】:

  • 提供更多关于不太相关的代码的详细信息,或者只是限制一次处理的图像数量。
  • 哦,对不起,我错过了,我没有得到 MemoryException,但我得到了我现在在 ResizeImage 方法中的按钮单击事件中收到的 ArgumentException... 太好了,我很友善回到我开始的地方
  • 1.您删除了ResizeImage 中的using? 2. 论据是什么?
  • 1.是的,我把它恢复到 2 之前的状态。它在我初始化 bmp 时发生但是我注意到,如果我只使用 1 个图像它可以工作,但是如果我处理许多图片,它会从 VS 调试器给我这个 ArgumentException,但是如果我运行它告诉我 OutOfMemory 而不是 ArgumentException 的可执行文件,可能有什么东西混在一起了?
  • 我注意到一件事:您正在使用 Graphics 对象,该对象需要在 using 块中,因为它也实现了 IDisposable。该块将进入ResizeImage
【解决方案2】:

好的,我终于解决了内存泄漏的问题,结果证明我确实在释放/处理图像,但它做得不够快,导致当您在处理大量非常大的图像后立即出现 outOufMemoryException其他。我尝试将所有内容都设为多线程,并一直等待 WorkingSet 变小但没有成功。

事实证明这比我想象的要容易,我所要做的就是把它放在我调整大小方法的末尾:

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

这似乎对调整大小为 10-20mb 且分辨率为 10000x10000 的大图像具有魔力。有人可以解释为什么 SpinWait 有帮助但不是正常的线程睡眠吗?每当我尝试让线程休眠时,它似乎也在休眠释放内存。

【讨论】:

    猜你喜欢
    • 2013-12-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 2010-11-23
    • 2014-02-27
    • 2013-09-06
    • 2018-05-07
    • 2015-07-13
    相关资源
    最近更新 更多