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();阻止它,但是,这没有帮助。
我该怎么办?
您需要处理实现IDispose
的所有东西,查看您的代码,它看起来像:
SourceImage
、CroppedImage
、TB
、G
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();
谢谢大家的帮助!