Frage

Ich bin ein Anfänger in WPF und versuche ein Heimprojekt, um mich mit der Technologie vertraut zu machen.Ich habe ein einfaches Formular, in dem der Benutzer eine Bilddatei auswählt und ich dann EXIF-Daten zusammen mit einer Miniaturansicht des Bildes anzeige.Das funktioniert gut, aber wenn ich eine RAW-Bilddatei (~9 MB) auswähle, kann es beim Laden des Daumens zu einer leichten Verzögerung kommen, daher dachte ich, ich könnte den BackgroundWorker verwenden, um das Bild zu dekodieren, und der Benutzer kann dann die EXIF-Daten anzeigen Sobald das Bild dekodiert wurde, wird es angezeigt.

Das BitmapSource-Objekt wird in der DoWork-Methode von BackgroundWorkers deklariert:

worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
    string filePath = args.Argument as string;

    BitmapDecoder bmpDecoder = BitmapDecoder.Create(new Uri(filePath), BitmapCreateOptions.None, BitmapCacheOption.None);
    BitmapSource bmpSource = bmpDecoder.Frames[0];
    bmpSource.Freeze(); //As suggested by Paul Betts

    args.Result = bmpSource;
};

Das Problem, auf das ich stoße, besteht darin, dass ich beim Versuch, die Quelle meines Image-Steuerelements in der RunWorkerCompleted-Methode festzulegen, eine Fehlermeldung erhalte, weil das Objekt einem anderen Thread gehört.

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
    imgThumb.Source = args.Result as BitmapSource;
};

Ich habe versucht, das zu verwenden imgThumb.Dispatcher.BeginInvoke() Methode zum Festlegen der Quelle, aber das hat auch nicht funktioniert, ich schätze, das liegt daran, dass es so ist args.Result das gehört einem anderen Thread und nicht dem imgThumb?Wie kann ich das umgehen?

Es könnte sein, dass ich meinen Dispatcher falsch codiert habe (das Folgende stammt aus dem Gedächtnis, ich habe gelöscht, was ich hatte).

imgThumb.Dispatcher.Invoke(new Action<BitmapSource>(
    delegate(BitmapSource src)
    {
        imgThumb.Source = src;
    }
), bmpSource);

Alle Vorschläge oder Ideen sind willkommen.

Aktualisieren

Ich habe meine DoWork-Methode geändert, um BitmapCreateOptions.None anstelle von .DelayCreation zu verwenden, aber jetzt erhalte ich beim Laden von RAW-Dateien die folgende Fehlermeldung (Canon .CR2-Dateien sind alles, was ich bisher getestet habe), der Code funktioniert gut für JPGs.Könnte dies ein Problem mit dem Canon-Codec sein, den ich installiert habe, damit ich die RAW-Dateien anzeigen kann?

Die Anwendung, die als Schnittstelle bezeichnet wird, die für einen anderen Thread untersagt wurde.(Ausnahme von HRESULT:0x8001010E (RPC_E_WRONG_THREAD))

War es hilfreich?

Lösung

Rufen Sie Freeze() für die BitmapSource auf und Sie werden dieses Problem nicht haben (Durch das Einfrieren werden die Threading-Einschränkungen aufgehoben, das Objekt wird jedoch unveränderlich gemacht).

Andere Tipps

Ich hatte genau das Beispielproblem und hatte das Glück, es lösen zu können.

Kurze Antwort:einpacken WriteableBitmap.Das hat allerdings einen kleinen Preis.

Lange Antwort.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top