【问题标题】:Out of memory exception in (System.Drawing())(System.Drawing()) 中的内存不足异常
【发布时间】:2013-02-14 05:18:34
【问题描述】:

我无法旋转图像。我要旋转的图像大小约为 300kB。当我将它从零度旋转到 360 度时,一次将角度增加一度,出现内存不足异常。它一直工作到 100 度。

这是我的代码:

private void button1_Click(object sender, EventArgs e)
{
    this.openFileDialog1.InitialDirectory  = System.Environment.SpecialFolder.MyComputer .ToString ();

    DialogResult result = this.openFileDialog1.ShowDialog();
    if (result == DialogResult.OK)
    {
        String pathfile = this.openFileDialog1.FileName ;
        meter = Image.FromFile(pathfile);

        pictureBox1.Image = meter;

        bitmapmeter = new Bitmap(meter);
        gmeter = Graphics.FromImage(bitmapmeter);
        w = bitmapmeter.Width;
        h = bitmapmeter.Height;
    }
}

private void button2_Click(object sender, EventArgs e)
{
    for (int angle = 0; angle < 360; angle = angle + 1)
    {
        bitmapmeter = new Bitmap(meter);    //create a bitmap for selected image//pictureBox2.Image = bitmapmeter;
        gmeter = Graphics.FromImage(bitmapmeter);

        rotate(angle);

        bitmapmeter.Dispose();

        gmeter.Dispose();
    }
    MessageBox.Show("Finished");
}

Bitmap newBitmap;
Graphics graphics;

private void rotate(int angle)
{
    newBitmap = new Bitmap(w, h);
    graphics = Graphics.FromImage(newBitmap);

    graphics.TranslateTransform((float)bitmapmeter.Width / 2, (float)bitmapmeter.Height / 2);
    graphics.RotateTransform(1);
    graphics.TranslateTransform(-(float)bitmapmeter.Width / 2, -(float)bitmapmeter.Height / 2);
    graphics.DrawImage(bitmapmeter, new Point(0, 0));

    newBitmap.Dispose();
    graphics.Dispose();
    //pictureBox2.Image = bitmapmeter;
}

【问题讨论】:

  • Winforms 会让你在尝试做这些事情时受苦。 WPF will make you happier
  • 如果您只需要两个(原始和旋转),为什么要创建 720 个 BitmapGraphics 实例?当然,你可以拨打GC.Collect(),但最好完全重写代码。
  • 您的 rotate 方法甚至不返回图像。这甚至像您期望的那样工作吗?
  • @NikolayKhil - 他实际上并没有创建 720 个 BitmapGraphics 实例,它实际上只有 360 个。
  • @NikolayKhil - 我只看到 rotate(int angle) 被调用了 360 次。

标签: c# system.drawing


【解决方案1】:

您的 Dispose 调用的顺序应该颠倒,位图不能被释放,因为图形对象仍在使用它。处理图形,然后处理位图,与创建它们的顺序相反。 (并且包装在一个自动处理的“使用”块中看起来会更好:)

using (bitmapmeter = new Bitmap(meter))    //create a bitmap for selected 
{
  using (gmeter = Graphics.FromImage(bitmapmeter))
  {
    rotate(angle);
  }
}

【讨论】:

    【解决方案2】:

    你应该在那里扔一个 GC.Collect,你可能在垃圾收集器有机会运行之前内存不足。

    【讨论】:

    • 您不需要调用 GC.Collect - 垃圾收集经过优化,可以在需要时运行。如果事情没有被清理干净,很可能是某些东西保留了对对象的引用。
    • 如果你必须调用 GC.Collect,那你就做错了,你永远不应该把 GC 搞得一团糟。
    • @sa_ddam213 [...] 在 prod 环境中。在开发环境中使用它可能是一个有用的诊断工具。
    猜你喜欢
    • 2011-01-09
    • 2010-10-05
    • 1970-01-01
    相关资源
    最近更新 更多