Hallo,
ich schreibe momentan ein kleines Bildbearbeitungsprogramm. Dieses Programm kann mehrere Bilder in Stapeln verarbeiten.
Während man an den Einstellungen spielt, lassen sich Vorschauen generieren, sobald man auf eines der Originalfotos klickt.
Das Problem dabei: Jedes Mal, wenn Einstellungen geändert werden und das Vorschaubild aktualisiert werden muss, wird das Bild als Datei komplett neu geladen: sehr langsam.
Deshalb habe ich eine kleine Klasse geschrieben, die sich mehrere Fotos "merkt". Die Logik sollte sich hiermit erklären:
public Bitmap GetImage(string path)
{
Bitmap returnImage = this.ImageCollection.GetImageByPath(path);
if (returnImage == null)
{
if (this.ImageCollection.Count >= this.MaxImages)
{
this.ImageCollection.DeleteImage(0);
}
returnImage = new Bitmap(path);
this.ImageCollection.Add(new ImagePack(path, returnImage));
}
return returnImage;
}
Nun das eigentliche Problem:
Wenn das Bild in der Liste vorhanden ist, wird dieses zurückgegeben. Wenn ich dieses zurückgegebene Bild auf der Form anzeigen will (darauf zugreifen will), wird eine Exception geschmissen:
"Ungültiger Parameter."
" bei System.Drawing.Image.get_Width()\r\n bei System.Drawing.Bitmap..ctor(Image original)\r\n bei DS.SimpleBorderCreator.WorkProcess.Worker_DoWork(Object sender, DoWorkEventArgs e) in D:\Visual Studio 2005\Projects\DS.SimpleBorderCreator\0.0.9.0\DS.SimpleBorderCreator\Classes\WorkProcess.cs:Zeile 233."
Wisst ihr, woran das liegt? Vielen Dank für eure Hilfe!
Gruß Dennis
Wenn ich dieses zurückgegebene Bild auf der Form anzeigen will (darauf zugreifen will), wird eine Exception geschmissen
Dann schick bitte noch denn Quelltext wo das Bild angezeigt wird.
Hallo Console.Beep(),
Damit sollte es nichts zu tun haben:
this.previewPictureBox.Image = ImageLoader.GetImage(imgPath);
Gruß Dennis
Hallo,
vielleicht hilft euch dieser Scrennshot weiter.. Eventuell hattet ihr schonmal so etwas ähnliches:
Gruß Dennis
Hm.. das ist wirklich merkwürdig.
Ich sehe da auch leider keinen Fehler in der Methode.
Tritt der Fehler generell auf oder nur wenn Einstellungen eines Bildes geändert wurden und das Vorschaubild aktualisiert werden muss?
Hallo Console.Beep(),
An den Einstellungen des Bildes wird nichts geändert.
Ablauf:
Gruß Dennis
Ich vermute ,dass das Problem zwischen Laden und Ausgeben des Bildes zu finden ist. Es könnte sein das ein Fehler in der Datei ist aber dann hätte das Prog schon beim Laden dir die Exception ausgeworfen.
Es ist jedenfalls komisch das alle Daten in der Bitmap nicht funzen und die Exception auslösen. An irgendeiner Stelle geht warscheinlich die Bitmap kaputt.
Also nochmal debuggen und schaun ob diese Fehler wie im Bild von Anfang bis Ende da sind, wenn nicht hätten wir die stelle genau eingegrenzt.
(Bitte korrigiert mich wenn ich falsch liege)
Was ich auf jeden Fall sagen kann: Die Bilder sind als Datei vollkommen in Ordnung.
Wenn die Abfrage
if (returnImage == null)
zutrifft, funktioniert das Laden des Bildes, da das Bild ja direkt in returnImage geladen und übergeben wird.
Der Fehler tritt nur auf, wenn das Bild aus der Collection geladen wird:
Bitmap returnImage = this.ImageCollection.GetImageByPath(path);
Gruß Dennis
Benutzt du Threads? Wenn ja verhaust du dich evtl. mit denen und einem evtl. falschen locking. Das produziert manchmal die komischsten Fehler....
Hallo jaensen,
ja ich benutze einen Backgroundworker. Was meinst du mit "evtl. falschen locking"?
Gruß Dennis
Wenn du aus mehreren Threads auf eine Resource zugreifst die nicht gelockt oder auf andere Art synchronisiert ist dann kann es passieren das der zugreifende Thread einen inkonsistenten Zustand vorfindet da der andere Thread seine Arbeit z.B. noch nicht vollständig abgeschlossen hat.
[Artikel] Multi-Threaded Programmierung ab Seite 8.
Hallo jaensen,
hmm das kann es eigentlich auch nicht sein. Es gibt nur einen Backgroundworker und dieser wird niemals gleichzeitig, immer nur hintereinander ausgeführt.
Gruß Dennis
Das verringert nur die Wahrscheinlichkeit da die GUI auch in einem eigenen Thread läuft der natürlich auch noch dazwischenfunken kann. Bei Zugriffen auf Controls bekommst du eine CrossThreadViolation bei normalen Member-Variablen in den meisten Fällen nicht. Also schau mal ob irgendwo parallele Zugriffe vorkommen können bevor du das Thema ausschließt, wenn du nur einen BackgroundWorker verwendest sollte ja der evtl. betroffene Code gut einzuschränken sein.
Es gibt eine DoWork-Klasse. In dieser Klasse wird der "ImageLoader" (siehe Methode im ersten Post) initialisiert, außerdem ist hier der Backgroundworker. Der Backgroundworker wird immer mal wieder gestartet und greift dann auf "ImageLoader" zu. Vermutlich stehen die Daten, sobald der Backgroundworker "neugestartet" wird, nicht mehr zur Verfügung. Wahrscheinlich ist das das Problem.
Habt ihr eine Idee, wie ich das ganze besser lösen kann?
Gruß Dennis
Hi dennisspohr!
Das kann ich nicht nachvollziehen, aber das könntest du durch einfaches Debugging herausfinden. Die Frage ist ja nur, ob dein ImageLoader (bzw. die Bitmaps) einmalig neu erstellt werden, oder bei jedem Aufruf durch den Backgroundworker.
Du kannst ja auch (wenn es dein Klassenaufbau erlaubt) einfach den Backgroundworker deaktivieren, so daß das ganze synchron ausgeführt wird. Dadurch kannst du die Fehlerquelle besser eingrenzen.
Schöne Grüße,
Christian
Weeks of programming can save you hours of planning
Hi MrSparkle,
Die Frage ist ja nur, ob dein ImageLoader (bzw. die Bitmaps) einmalig neu erstellt werden, oder bei jedem Aufruf durch den Backgroundworker.
Der ImageLoader wird im gesamten Programmablauf nur einmal erstellt - genauso wie der Backgroundworker.
Du kannst ja auch (wenn es dein Klassenaufbau erlaubt) einfach den Backgroundworker deaktivieren, so daß das ganze synchron ausgeführt wird.
Das erfodert ein wenig Umstruktierung - aber ich werde es mal probieren.
Gruß Dennis
Hallo zusammen,
ich habe alles mal in einem einzigen Thread ausgeführt - immernoch der gleiche Fehler.
Gruß Dennis
Hi dennisspohr,
dann poste doch mal die ImageLoader-Klasse, oder die (Bitmap-)relevanten Funktionen.
Du kannst übrigens beim Debuggen die Integrität der Bitmap-Objekte testen, indem du zu verschiedenen Zeitpunkten im Programm das Bitmap mit der Save-Methode in eine Datei speicherst.
Dann sollte der gleiche Fehler auftreten wie beim Zeichnen, und du kannst die Fehlerursache besser eingrenzen.
Schöne Grüße,
Christian
Weeks of programming can save you hours of planning
Hallo zusammen,
ich habe mein Projekt kopiert und alles irrelevante rausgenommen.
Was Witzige ist: Nun funktioniert es! Ich habe keinlei Ahnung warum.
Ich werde in den nächsten Tagen mal genau suchen / experimentieren.
Nochmal Danke für eure Hilfe!
Gruß Dennis