Bagaimana cara mengatasi masalah penimpaan file terkait yang berpotensi membuang ini?

Saya memuat file Bitmap 50x50 dan kemudian mengisinya dengan satu warna acak saat startup program. Kemudian simpan hasilnya ke file yang sama dan tetapkan ke PictureBox, tetapi mengalami masalah penulisan file dan "Terjadi kesalahan umum di GDI+", dll.

Bagaimana melakukan ini dengan benar sehingga saya dapat terus mengulanginya, (buka bitmap, cat dengan warna acak, simpan dan tetapkan ke picturebox.Image)?

Sunting:

  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 ( );
  }

person Joan Venge    schedule 25.02.2010    source sumber
comment
Apakah objek Graphics mengelola bitmap setelah panggilan ke Graphics.FromImage? Jika demikian, mungkin Anda perlu berinteraksi dengan bitmap melalui objek Graphics, atau melepaskannya dari objek grafik sebelum Anda mencoba Save atau Dispose?   -  person Scott Smith    schedule 25.02.2010
comment
Terima kasih, tapi bagaimana Anda melakukannya?   -  person Joan Venge    schedule 25.02.2010


Jawaban (3)


Adaptasi sederhana, dengan usings yang tepat, akan terlihat seperti:

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;   
}
person Henk Holterman    schedule 25.02.2010
comment
Terima kasih Henk. Apakah penggunaan kata kunci akan bertumpuk seperti itu? Bagaimana pengaruhnya dalam kasus tersebut? Semuanya termasuk dalam cakupan yang sama? - person Joan Venge; 26.02.2010
comment
@Joan, using beroperasi seperti if(): 1 pernyataan atau beberapa pernyataan dalam kurung kurawal. Indentasi di sini adalah hal yang tidak biasa tetapi merupakan praktik yang diterima. - person Henk Holterman; 26.02.2010
comment
Terima kasih Henk. Apa kamu yakin? Saya mencoba beberapa kali tetapi muncul kesalahan GDI umum di bmp2.Save(@C:\temp\pretty.bmp);. - person Joan Venge; 26.02.2010
comment
@Joan: Maaf, Anda benar. Saya menggunakan 2 nama file berbeda. Clone() tampaknya tidak cukup dalam. - person Henk Holterman; 26.02.2010

Saat Anda menggunakan konstruktor Bitmap yang mengambil parameter jalur, file tetap terbuka sampai Anda membuang Bitmap. Anda perlu memuat bitmap dari Stream, dan menutup Stream agar file ditutup. Ini seharusnya berfungsi dengan baik:

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;
}
person Thomas Levesque    schedule 25.02.2010
comment
Anda juga perlu membuang Bitmap, Graphics, dan Brush. (Kecuali Anda menggunakan SolidBrushes.Black) - person SLaks; 25.02.2010

Oh. Anda memerlukan file yang berbeda untuk setiap gambar Anda, jika tidak, Anda akan menimpa gambar pertama demi gambar kedua. Masalahnya adalah gambar tersebut hanya dapat dibaca nanti, ketika benar-benar diperlukan.

Pilihan lainnya adalah menyimpan gambar di aliran memori, bukan di file.

person Vlad    schedule 25.02.2010