2

I created a WPF project which has a settings window as main window and from there I open a game window. When opening the game window, the following code creates one long image strip out of several images.

var target = new System.Drawing.Bitmap((int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var graphics = System.Drawing.Graphics.FromImage(target);
graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;

int i = 0;
foreach (Image img in images)
{
     System.Drawing.Image drawingImg = ConvertWpfImageToImage(img);
     System.Drawing.Bitmap source = new System.Drawing.Bitmap(drawingImg);
     graphics.DrawImage(source, i, 0);
     i += 320;
}
target.Save(@".\resources\images\conveyerBeltSymbols\bigPicture.png");

This seems to be no problem (although I am saving a bitmap image as png, I know that) at the first time but when I close the second window and try to open it again (without closing the first window too) I get External Exception was unhandled. A generic error occurred in GDI+.

I tried adding Dispose() to both graphics and target and also tried to add ImageFormat.Png to the target.Save method but nothing worked for me.

Has anyone got a solution?

jera
  • 302
  • 4
  • 30
  • Are you using `Image.FromFile` at any point to load the `bigPicture.png` image? That method will keep the file locked until your process exits, which would prevent the `Save` method from overwriting it. – Richard Deeming Jul 17 '13 at 18:47
  • `slider.ImageSource = new BitmapImage(new Uri(@".\resources\images\conveyerBeltSymbols\bigPicture.png", UriKind.Relative));` is how I "load" the picture. I also tried setting `slider.ImageSource = null` at window closing but that didn't help either – jera Jul 17 '13 at 19:15
  • That will keep the file locked. Have a look at [this answer](http://stackoverflow.com/a/6430416/124386) - it's in VB, but it should be fairly simple to translate. – Richard Deeming Jul 17 '13 at 19:20

2 Answers2

2

Loading the picture using the new BitmapImage(Uri) constructor will keep the file locked. Try using:

var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(@".\resources\images\conveyerBeltSymbols\bigPicture.png", UriKind.Relative);
image.EndInit();

slider.ImageSource = image;
Richard Deeming
  • 29,830
  • 10
  • 79
  • 151
0

Ensure that you are properly using or calling Dispose() on each of the GDI objects... Including your Bitmap and Image. This should resolve your issues. It's likely you're not releasing unmanaged resources properly.

Haney
  • 32,775
  • 8
  • 59
  • 68
  • As I wrote, I already tried `target.Dispose()` and `graphics.Dispose` after I save the Bitmap but that didn't solve it. – jera Jul 17 '13 at 19:14