Joan Venge
Joan Venge

Reputation: 331130

How to solve this potentially dispose related file overwrite issue?

I am loading a 50x50 Bitmap file and then filling it a single random color at program startup. Then save the result onto the same file and assign it to a PictureBox, but running into file write problems and "A generic error occurred in GDI+", etc.

How to do this properly so that I can continually repeat this, (open bitmap, paint it random color, save and assign to picturebox.Image)?

EDIT:

  public Form1 ( )
  {
   InitializeComponent ( );

   //Bitmap bmp = new Bitmap ( 50, 50 );
   Bitmap bmp = new Bitmap ( @"C:\temp\pretty.bmp" );

   Graphics g = Graphics.FromImage ( bmp );
   Brush b = new SolidBrush ( Color.Red );
   g.FillRectangle ( b, 0, 0, 49, 49 );
   bmp.Save ( @"C:\temp\pretty.bmp" );

   this.pictureBox1.Image = ( Image ) bmp.Clone ( );
   //bmp.Dispose ( );
  }

Upvotes: 0

Views: 367

Answers (3)

Henk Holterman
Henk Holterman

Reputation: 273294

A simple adaptation, with the proper usings, would look like:

private void Form1_Load(object sender, EventArgs e)
{
    Bitmap bmp2;

    using (Bitmap bmp1 = new Bitmap(@"C:\temp\pretty.bmp"))
    {
//Edit: Clone was keeping a link between bmp1 and bmp2 somehow
       // bmp2 = (Bitmap)bmp1.Clone();
       IntPtr hbmp = bmp1.GetHbitmap();
       bmp2 = Bitmap.FromHbitmap(hbmp);     
    }

    using (Graphics g = Graphics.FromImage(bmp2))
    using (Brush b = new SolidBrush(Color.Red))
    {
        g.FillRectangle(b, 0, 0, 49, 49);

        bmp2.Save(@"C:\temp\pretty.bmp");
    }

    this.pictureBox1.Image = bmp2;   
}

Upvotes: 3

Thomas Levesque
Thomas Levesque

Reputation: 292465

When you use the Bitmap constructor that takes a path parameter, it keeps the file open until you dispose the Bitmap. You need to load the bitmap from a Stream, and close the Stream so that the file is closed. This should work fine :

public Form1 ( )
{
    InitializeComponent ( );

     Bitmap bmp = null;
     using (Stream stream = File.OpenRead(@"C:\temp\pretty.bmp"))
     {
         bmp = new Bitmap(stream);
     }

     using (Graphics g = Graphics.FromImage ( bmp ))
     using (Brush b = new SolidBrush ( Color.Red ))
     {
         g.FillRectangle ( b, 0, 0, 49, 49 );
     }
     bmp.Save ( @"C:\temp\pretty.bmp" );
     this.pictureBox1.Image = bmp;
}

Upvotes: 2

Vlad
Vlad

Reputation: 35594

Oh. You need a different file for each of your images, otherwise you overwrite the first by the second. The things is that the image may be read only later, when it's actually needed.

Another option would be to store images in memory streams, not in files.

Upvotes: 1

Related Questions