Entwickler-Ecke

Multimedia / Grafik - Bild dynamisch laden...


tomycat - Mi 05.08.15 14:34
Titel: Bild dynamisch laden...
hallo,
ich will einfach per link Eingabe und ein Button ein Bild laden. Das Bild liegt urspürnglich immer erstmal im Web.

1.C:/temp.jpg löschen
2.Das Bild vom Internet auf den Ort C:/temp.jpg kopieren.
3.Das Bild von C:/temp.jpg in mein Projekt laden.

Wenn ich das Programm starte, und den Pfad eingebe sowie den Button klicke,dann gehts.
Nach pfad änderung sowie ein Button klick wird das neue Bild nicht mehr geladen.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
  if (System.IO.File.Exists(@"C:\\temp.jpg"))
            {
                // Use a try block to catch IOExceptions, to 
                // handle the case of the file already being 
                // opened by another process. 
                try
                {
                    System.IO.File.Delete(@"C:\\temp.jpg");
                }
                catch (System.IO.IOException e)
                {
                    //  Console.WriteLine(e.Message);
                    //   return;
                }
            }
            // bild runterladen

            try
            {
                WebClient Webclient1 = new WebClient();
                Webclient1.DownloadFile(bildx.Text, @"C:\temp.jpg");

                // Bild öffnen
                FileStream imageStream = new FileStream("C:\\temp.jpg", FileMode.Open, FileAccess.Read);

                // Image der Picturebox setzen
                pictureBox_bildx.Image = System.Drawing.Image.FromStream(imageStream);

            }
            catch (Exception ex)
            {
               

                MessageBox.Show("keine Bild gefunden");

            }


Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt


Ralf Jansen - Mi 05.08.15 15:11

Das Image das von Image.FromStream geöffnet wird braucht weiterhin das File und wird ein Handle auf das File behalten. Du kannst solange also das File weder löschen noch austauschen bis du das Image (oder den Stream) freigegeben hast. Hier also, bevor du pictureBox_bildx.Image zuweist, das alte Bild das möglicherweise vorher da drin war explizit disposen. Am besten gleich als erstes nach dem Test auf File.Exists

Nebenbei da du mit dem imageStream nichts machst kannst du auch gleich Image.FromFile benutzen. Denn Stream zu haben hilft hier so nicht.


jfheins - Mi 05.08.15 19:40

user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Nebenbei da du mit dem imageStream nichts machst kannst du auch gleich Image.FromFile benutzen. Denn Stream zu haben hilft hier so nicht.

In meinen Augen könnte man auch gleich auf die (überflüssige) Datei verzichten und stattdessen das Bild aus dem Speicher laden. Ungefähr so:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  WebClient Webclient1 = new WebClient();
  var bytes = await Webclient1.DownloadDataTaskAsync(bildx.Text);

  // Bild öffnen
  using (var imageStream = new MemoryStream(bytes)) {
    // Image der Picturebox setzen
    pictureBox_bildx.Image = System.Drawing.Image.FromStream(imageStream);
  }


Ist jetzt nicht getestet, sollte aber die Idee vermitteln. Grund wäre u.a., dass man eine Fehlerquelle (Festplattenzugriff) komplett eliminiert, und man eh nicht direkt in C:\ schreiben sollte.


tomycat - Mi 05.08.15 20:55

mega thx !!!

@jfheins

VS will folgende Änderung von...

private void artikel(string eingabe)

...auf...

private async void artikel(string eingabe)

ääähh wieso?


Ralf Jansen - Mi 05.08.15 21:20

Zitat:
ääähh wieso?


Guckst du hier [https://msdn.microsoft.com/de-de/library/hh191443.aspx] für eine umfassende Erklärung.

Zusammenfassend dein Code würde in Webclient.DownloadFile hängen bis der Download abgeschlossen ist. Heißt z.B. die UI deiner Anwendung würde sich während der Ausführung nicht aktualisieren was häßliche Auswirkungen haben kann (wer sollte die UI auch zeichnen deine Anwendung steht ja bis die Methode zu ende ist). Durch das async await Pattern und das Benutzen einer asynchronen Methode wie DownloadDataTaskAsync (gibt genauso eine asnychrone Methode für DownloadFile) wird an dieser Stelle zwar auch bis zum Abschluss der asynchronen Methode gewartet aber der Thread steht nicht und kann weiter Events wie eben zum Beispiel das zeichnen der UI ausführen.