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

本文关键字:处理 内存 泄漏 TextureBrush | 更新日期: 2023-09-27 18:27:05

我正在开发一个循环菜单应用程序。

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

嗯,我找到了一个代码片段,用于在图像或位图中裁剪图片C#裁剪圆或:

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();阻止它,但是,这没有帮助。

我该怎么办?

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

您需要处理实现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;
}

嗯。。。这似乎是一种非常低效的位图剪切方式。以下是我的做法:

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 s。此方法只创建两个位图,并确保处理其中一个位图,以及用于创建掩码的Graphics对象和GraphicsPath

好吧,解决了。

正如您所说,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();

谢谢大家的帮助!