正确的方式来处理图像/位图和图片框

我正在尝试开发Windows Mobile 6(在WF / C#中)应用程序。 只有一个窗体,窗体上只有一个PictureBox对象。 在这上面我画了所有想要的控件或任何我想要的。

我正在做两件事。 绘制自定义形状并从.png文件加载位图。

下一行在加载时locking文件(这是一个不希望的情况):

Bitmap bmp = new Bitmap("file.png"); 

所以我正在使用另一种方式来加载位图。

 public static Bitmap LoadBitmap(string path) { using (Bitmap original = new Bitmap(path)) { return new Bitmap(original); } } 

这是我猜得慢得多,但我不知道有更好的方式来加载图像,同时快速释放文件locking。

现在,当绘制图像时,我使用的方法是:

 public void Draw() { Bitmap bmp = new Bitmap(240,320); Graphics g = Graphics.FromImage(bmp); // draw something with Graphics here. g.Clear(Color.Black); g.DrawImage(Images.CloseIcon, 16, 48); g.DrawImage(Images.RefreshIcon, 46, 48); g.FillRectangle(new SolidBrush(Color.Black), 0, 100, 240, 103); pictureBox.Image = bmp; } 

这似乎是某种内存泄漏。 如果我一直这样做,应用程序最终会崩溃。

所以我有三个问题:

1.)什么是从文件加载位图而不locking文件的更好的方法?

2)什么对象需要手动处理的Draw()函数(以什么顺序),所以没有内存泄漏,没有ObjectDisposedException抛出?

3.)如果pictureBox.Image被设置为bmp,就像在代码的最后一行一样,将pictureBox.Image.Dispose()只处理与维护pictureBox.Image或底层Bitmap相关的资源吗?

1:我不知道它是否在WM工作,但试试这个:

 FileStream bitmapFile = new FileStream("mybitmap.bmp", FileMode.Open, FileAccess.Read, FileShare.ReadWrite); Image loaded = new Bitmap(bitmapFile); 

2:必须处理SolidBrush 。 处理有一个通用的规则。 – >“由你实例化的每个对象,实现configuration必须手动configuration,当对象一个return / ref / out值时,

在这种情况下,最好使用using语句

 using (new objecttodispose){ ..... } 

using语句将确保在任何情况下调用Dispose() (例如exception)。

3: Dispose()将释放位图资源。

我不认为有真正的内存泄漏 。 问题是,你不处理旧的位图,这是由GC来清理的东西。 但是没有确定性的方式来说明什么时候会发生。

所以我认为如果你要循环播放大量的图片,你会看到一些记忆力的增加,而在其他的一些情况下,它会下降或抵制一个位置。

我没有对它进行testing,但也许这会有助于使其更确定:

 public void Draw() { Bitmap bmp = new Bitmap(240,320); using(var g = Graphics.FromImage(bmp)) using(var solidBrush = SolidBrush(Color.Black)) { // draw something with Graphics here. g.Clear(Color.Black); g.DrawImage(Images.CloseIcon, 16, 48); g.DrawImage(Images.RefreshIcon, 46, 48); g.FillRectangle(solidBrush, 0, 100, 240, 103); //Backup old image in pictureBox var oldImage = pictureBox.Image; pictureBox.Image = bmp; //Release resources from old image if(oldImage != null) ((IDisposable)oldImage).Dispose(); } } 

更新

还有另一个灵感来自jack30lena的想法:

 public static Bitmap LoadBitmap(string path) { //Open file in read only mode using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read)) //Get a binary reader for the file stream using (BinaryReader reader = new BinaryReader(stream)) { //copy the content of the file into a memory stream var memoryStream = new MemoryStream(reader.ReadBytes((int)stream.Length)); //make a new Bitmap object the owner of the MemoryStream return new Bitmap(memoryStream); } } 

我的第二个代码示例背后的想法是摆脱文件句柄,并将文件内容复制到内存中。 之后,位图将通过调用oldImage.Dispose()来获取将放置在我的第一个示例中的MemoryStream的所有权。

通过使用这种方法,内存中永远不应该有两个以上的图像,只有通过真正大的图像或less量的RAM才能导致OutOfMemoryExceptionexception。