TextureBrush导致内存泄漏,即使我处理它

时间:2012-03-08 14:31:08

标签: c# memory-leaks gdi+

我正在开发一个圆形菜单应用程序。

在我使用位图作为背景之前,我必须将其裁剪为圆形。

好吧,我找到了一个用于裁剪图片C# crop circle in a image or bitmap或:

的代码段
public System.Drawing.Image x(string sourceFile, int circleUpperLeftX, int circleUpperLeftY, int circleDiameter)
{
    Bitmap SourceImage = new Bitmap(System.Drawing.Image.FromFile(sourceFile));
    Rectangle CropRect = new Rectangle(circleUpperLeftX, circleUpperLeftY, circleDiameter, circleDiameter);
    Bitmap CroppedImage = SourceImage.Clone(CropRect, SourceImage.PixelFormat);
    TextureBrush TB = new TextureBrush(CroppedImage);
    Bitmap FinalImage = new Bitmap(circleDiameter, circleDiameter);
    Graphics G = Graphics.FromImage(FinalImage);
    G.FillEllipse(TB, 0, 0, circleDiameter, circleDiameter);
    return FinalImage;
}

但是在第6行中,代码会导致内存泄漏。

好吧,我尝试添加TB.Dispose();为了防止它,但是,这没有帮助。

我该怎么办?

3 个答案:

答案 0 :(得分:5)

您需要处理实现IDispose的所有内容,并查看您的代码,它看起来像:

SourceImageCroppedImageTBG

FinalImage没有被释放,因为它被返回,但是使用FinalImage的任何东西都有责任处理它。

正如PowerRoy所提到的,使用块将为你处理。

以下是使用多个使用块的重构示例:

public Image CreateFinalImage(string sourceFile, int circleUpperLeftX, int circleUpperLeftY, int circleDiameter) {
  Bitmap finalImage = new Bitmap(circleDiameter, circleDiameter);
  Rectangle cropRect = new Rectangle(circleUpperLeftX, circleUpperLeftY, circleDiameter, circleDiameter);

  using (Bitmap sourceImage = new Bitmap(System.Drawing.Image.FromFile(sourceFile)))
  using (Bitmap croppedImage = sourceImage.Clone(cropRect, sourceImage.PixelFormat))
  using (TextureBrush tb = new TextureBrush(croppedImage))
  using (Graphics g = Graphics.FromImage(finalImage)) {
    g.FillEllipse(tb, 0, 0, circleDiameter, circleDiameter);
  }

  return finalImage;
}

答案 1 :(得分:0)

嗯...这似乎是一种非常低效的剪裁位图的方法。我就是这样做的:

public Image x(string sourceFile, int circleUpperLeftX, int circleUpperLeftY, int circleDiameter) {
    using(Bitmap sourceImage = new Bitmap(sourceFile), GraphicsPath p = new GraphicsPath()) {
        Bitmap destImage = new Bitmap(circleDiameter, circleDiameter, sourceImage.PixelFormat);

        p.AddEllipse(circleUpperLeftX, circleUpperLeftY, circleDiameter, circleDiameter);

        using(Graphics g = Graphics.FromImage(destImage)) {
            g.SetClip(p);
            g.DrawImageUnscaled(sourceImage, 0, 0);
        }

        return destImage;
    }
}

现在,你的内存泄漏的原因可能是忘记处理所有那些临时的Bitmap。此方法仅创建两个位图,并确保配置其中一个位图,以及Graphics对象和用于创建蒙版的GraphicsPath

答案 2 :(得分:0)

好吧,解决了它。

正如你所说,textbrush不会导致内存泄漏。

我曾经使用过这段代码:

pictureBox1.Image = menu.Draw(bos, new Point(Cursor.Position.X - Left, Cursor.Position.Y - Top), (int)DateTime.Now.Subtract(sabit).TotalMilliseconds / 4);

当我使用它时,我指的是在为其分配新的位图之前处理PictureBox的图像可以防止内存泄漏。

Bitmap result = menu.Draw(bos, new Point(Cursor.Position.X - Left, Cursor.Position.Y - Top), (int)DateTime.Now.Subtract(sabit).TotalMilliseconds / 4);
        if (pictureBox1.Image != null)
            pictureBox1.Image.Dispose();
        pictureBox1.Image = (Image)result.Clone();
        result.Dispose();

谢谢大家的帮助!