C# 如果我需要另一个 class 中的位图,请使用 Dispose()
C # Use Dispose() if i need Bitmap in another class
我有这个 class 来裁剪图像:
public static Bitmap Crop(Bitmap img_crop, int w, int h, int x, int y)
{
Image img_crop = img_crop;
Bitmap bmp_crop = new Bitmap(w, h, PixelFormat.Format24bppRgb);
bmp_crop.SetResolution(80, 60);
Graphics gfx = Graphics.FromImage(bmp_crop);
gfx.SmoothingMode = SmoothingMode.AntiAlias;
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(img_cortar, new Rectangle(0, 0, w, h), x, y, w, h, GraphicsUnit.Pixel);
//bmp_crop.Save("test.bmp");
// Dispose to free up resources
img_crop.Dispose();
//bmp_crop.Dispose();// <------------ How to use this and pass Bitmap to the next class?
gfx.Dispose();
Class2(bmp_crop);
return bmp_crop;
}
我需要在另一个class中裁剪图像,如果我使用Dispose()(bmp_crop.Dispose();
),在接下来的class中我得到一个参数错误,我该如何丢弃Bitmap 并且仍然可以在下一个 class?
中使用它
public static Bitmap Class2(Bitmap bmp_crop)
{
...
}
- 看看您的代码实际做了什么,它是 调整 图像的大小,而不是裁剪它 - 因此您应该将此方法重命名为
Resize
,而不是 Crop
.
- 只有
IDisposable
对象的“所有者”才能调用 .Dispose()
或使用 using
块。
- “所有者”是指控制
IDisposable
对象生命周期的父作用域或生命周期。
- 这可以是一个 class(如果
IDisposable
存储为一个字段)或者它是一个方法(如果 IDisposable
不应该超过方法或范围在方法内)。
- 因为我假设您不打算让您的
Crop
方法限制 Bitmap img_crop
(源输入图像)的生命周期,您的 Crop
方法 必须不调用bmp_crop.Dispose()
!
- 当一个方法创建一个新的
IDisposable
对象并 return 时,该方法将“拥有”该对象,直到它 return 删除它 - 这意味着如果异常是抛出到方法内部,那么该方法必须处理该对象 - 这是在创建对象后立即使用 try/catch
完成的。
- 在您不再需要
Graphics
对象后立即处理它是非常重要的。 System.Drawing
中的一次性类型是原生 Windows GDI 对象的包装器,它会在您的进程中耗尽 GDI 句柄 - 泄漏 GDI 句柄是不好的,因为最终您会 运行-out 然后所有图形操作会突然停止工作(这就是为什么很多写得不好的 WinForms 程序在一段时间后开始出现图形故障的原因)。
- 此外,
img_crop
和 bmp_crop
是变量名的糟糕选择,因为名称没有描述变量是什么,而且匈牙利表示法很糟糕。
- 在下面的示例中,我对输入图像使用
source
,对输出图像使用 cropped
。
这是我的做法:
public static Bitmap Resize( Bitmap source, int w, int h, int x, int y )
{
Bitmap resized = new Bitmap( w, h, PixelFormat.Format24bppRgb );
try
{
cropped.SetResolution(80, 60);
using( Graphics g = Graphics.FromImage( cropped ) )
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawImage( source, new Rectangle( 0, 0, w, h ), x, y, w, h, GraphicsUnit.Pixel );
}
// Pass the image to the other class/method/etc:
Class2( resized );
return resized; // Return the image to the caller, who now "owns" the image and its their responsibility to dispose of it.
}
catch( Exception ex )
{
resized.Dispose();
throw;
}
}
如果你不打算在调用你的Class2
方法后returncropped
给调用者,那么你应该删除try/catch
而不是使用 using
块,像这样:
public static Bitmap Resize(Bitmap source, int w, int h, int x, int y)
{
using( Bitmap resized = new Bitmap( w, h, PixelFormat.Format24bppRgb ) )
{
cropped.SetResolution(80, 60);
using( Graphics g = Graphics.FromImage( resized ) )
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawImage( source, new Rectangle( 0, 0, w, h ), x, y, w, h, GraphicsUnit.Pixel );
}
// Pass the image to the other class/method/etc:
Class2( resized );
}
}
我有这个 class 来裁剪图像:
public static Bitmap Crop(Bitmap img_crop, int w, int h, int x, int y)
{
Image img_crop = img_crop;
Bitmap bmp_crop = new Bitmap(w, h, PixelFormat.Format24bppRgb);
bmp_crop.SetResolution(80, 60);
Graphics gfx = Graphics.FromImage(bmp_crop);
gfx.SmoothingMode = SmoothingMode.AntiAlias;
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(img_cortar, new Rectangle(0, 0, w, h), x, y, w, h, GraphicsUnit.Pixel);
//bmp_crop.Save("test.bmp");
// Dispose to free up resources
img_crop.Dispose();
//bmp_crop.Dispose();// <------------ How to use this and pass Bitmap to the next class?
gfx.Dispose();
Class2(bmp_crop);
return bmp_crop;
}
我需要在另一个class中裁剪图像,如果我使用Dispose()(bmp_crop.Dispose();
),在接下来的class中我得到一个参数错误,我该如何丢弃Bitmap 并且仍然可以在下一个 class?
public static Bitmap Class2(Bitmap bmp_crop)
{
...
}
- 看看您的代码实际做了什么,它是 调整 图像的大小,而不是裁剪它 - 因此您应该将此方法重命名为
Resize
,而不是Crop
. - 只有
IDisposable
对象的“所有者”才能调用.Dispose()
或使用using
块。- “所有者”是指控制
IDisposable
对象生命周期的父作用域或生命周期。- 这可以是一个 class(如果
IDisposable
存储为一个字段)或者它是一个方法(如果IDisposable
不应该超过方法或范围在方法内)。
- 这可以是一个 class(如果
- 因为我假设您不打算让您的
Crop
方法限制Bitmap img_crop
(源输入图像)的生命周期,您的Crop
方法 必须不调用bmp_crop.Dispose()
!
- “所有者”是指控制
- 当一个方法创建一个新的
IDisposable
对象并 return 时,该方法将“拥有”该对象,直到它 return 删除它 - 这意味着如果异常是抛出到方法内部,那么该方法必须处理该对象 - 这是在创建对象后立即使用try/catch
完成的。 - 在您不再需要
Graphics
对象后立即处理它是非常重要的。System.Drawing
中的一次性类型是原生 Windows GDI 对象的包装器,它会在您的进程中耗尽 GDI 句柄 - 泄漏 GDI 句柄是不好的,因为最终您会 运行-out 然后所有图形操作会突然停止工作(这就是为什么很多写得不好的 WinForms 程序在一段时间后开始出现图形故障的原因)。 - 此外,
img_crop
和bmp_crop
是变量名的糟糕选择,因为名称没有描述变量是什么,而且匈牙利表示法很糟糕。- 在下面的示例中,我对输入图像使用
source
,对输出图像使用cropped
。
- 在下面的示例中,我对输入图像使用
这是我的做法:
public static Bitmap Resize( Bitmap source, int w, int h, int x, int y )
{
Bitmap resized = new Bitmap( w, h, PixelFormat.Format24bppRgb );
try
{
cropped.SetResolution(80, 60);
using( Graphics g = Graphics.FromImage( cropped ) )
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawImage( source, new Rectangle( 0, 0, w, h ), x, y, w, h, GraphicsUnit.Pixel );
}
// Pass the image to the other class/method/etc:
Class2( resized );
return resized; // Return the image to the caller, who now "owns" the image and its their responsibility to dispose of it.
}
catch( Exception ex )
{
resized.Dispose();
throw;
}
}
如果你不打算在调用你的Class2
方法后returncropped
给调用者,那么你应该删除try/catch
而不是使用 using
块,像这样:
public static Bitmap Resize(Bitmap source, int w, int h, int x, int y)
{
using( Bitmap resized = new Bitmap( w, h, PixelFormat.Format24bppRgb ) )
{
cropped.SetResolution(80, 60);
using( Graphics g = Graphics.FromImage( resized ) )
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawImage( source, new Rectangle( 0, 0, w, h ), x, y, w, h, GraphicsUnit.Pixel );
}
// Pass the image to the other class/method/etc:
Class2( resized );
}
}