我正在开发一个圆形菜单应用程序。
在我使用位图作为背景之前,我必须将其裁剪为圆形。
好吧,我找到了一个用于裁剪图片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();为了防止它,但是,这没有帮助。
我该怎么办?
答案 0 :(得分:5)
您需要处理实现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;
}
答案 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();
谢谢大家的帮助!