[英]TextureBrush Causes Memory Leak, Even If I Dispose It
I am working on a circular menu application. 我正在研究圆形菜单应用程序。
Before I use a bitmap as background, I must crop it as a circle. 在使用位图作为背景之前,必须将其裁剪为圆形。
Well, I found a code snippet for cropping the picture C# crop circle in a image or bitmap or: 好吧,我找到了一个代码片段,用于在图像或位图中裁剪图片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;
}
But the code causes memory leak after a while in line 6. 但是代码在第6行过一段时间后会导致内存泄漏。
Well, I tried adding TB.Dispose(); 好吧,我尝试添加TB.Dispose();。 to prevent it but, that didn't help.
防止它,但这没有帮助。
What should I do? 我该怎么办?
You need to dispose everything that implements IDispose
, and looking at your code, it looks like: 您需要处理实现
IDispose
所有内容,并查看您的代码,如下所示:
SourceImage
, CroppedImage
, TB
, G
SourceImage
, CroppedImage
, TB
, G
FinalImage
does not get disposed in this function since it is getting returned, but whatever is using FinalImage
has the responsibility to dispose of it. 由于会返回
FinalImage
,因此不会将其丢弃,但是无论使用FinalImage
有责任对其进行处置。
As PowerRoy mentioned, using blocks will take of the disposing for you. 如PowerRoy所述,使用块将为您处理。
Here is a refactored example using multiple using blocks: 这是一个使用多个using块的重构示例:
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;
}
Hm... that appears to be a very inefficient way of clipping a bitmap. 嗯...这似乎是裁剪位图的一种非常低效的方式。 Here's how I'd do it:
这是我的处理方式:
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;
}
}
Right now, the reason for your memory leak is probably forgetting to dispose all those temporary Bitmap
s. 现在,内存泄漏的原因可能是忘记处置所有这些临时
Bitmap
。 This method only creates two bitmaps and makes sure to dispose one of them, along with the Graphics
object and the GraphicsPath
used to create the mask. 此方法仅创建两个位图,并确保将其中之一以及用于创建遮罩的
Graphics
对象和GraphicsPath
一起放置。
Well, Solved It. 好了,解决了。
As you said, textbrush is not causing the memory leak. 如您所说,textbrush不会导致内存泄漏。
I used to use this code: 我曾经使用以下代码:
pictureBox1.Image = menu.Draw(bos, new Point(Cursor.Position.X - Left, Cursor.Position.Y - Top), (int)DateTime.Now.Subtract(sabit).TotalMilliseconds / 4);
When I used this, I mean Disposing PictureBox's Image before assigning a new Bitmap to it prevented the memory leak. 当我使用它时,我的意思是在分配一个新的位图之前先处理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();
Thank you all for your help! 谢谢大家的帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.