Вопрос

Я новичок в работе с WPF и пробую домашний проект, чтобы ознакомиться с технологией.У меня есть простая форма, в которой пользователь выбирает файл изображения, затем я отображаю данные EXIF вместе с миниатюрой изображения.Это работает нормально, но когда я выбираю файл изображения RAW (~ 9 МБ), может возникнуть небольшая задержка при загрузке thumb, поэтому я подумал, что могу использовать BackgroundWorker для декодирования изображения, и пользователь сможет просмотреть данные EXIF, а затем, когда изображение будет декодировано, оно отобразится.

Объект BitmapSource объявляется в методе BackgroundWorkers DoWork:

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

проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь установить источник моего элемента управления изображением в методе RunWorkerCompleted, я получаю сообщение об ошибке, потому что объект принадлежит другому потоку.

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

Я попробовал использовать imgThumb.Dispatcher.BeginInvoke() метод для установки источника, но это тоже не сработало, я думаю, это потому, что это args.Result который принадлежит другому потоку, а не imgThumb?Как я могу обойти это?

Возможно, я неправильно кодировал свой диспетчер (следующее взято из памяти, я удалил то, что у меня было).

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

Любые предложения или идеи приветствуются.

Обновить

Изменил свой метод DoWork на использование BitmapCreateOptions.Нет , скорее нет .DelayCreation, но теперь я получаю следующую ошибку при загрузке RAW-файлов (Canon.Файлы CR2 - это все, что я тестировал на сегодняшний день), код отлично работает для jpg.Может ли это быть проблемой с кодеком Canon, который я установил, чтобы позволить мне отображать файлы RAW?

Приложение вызвало интерфейс , который был настроен для другого потока.(Исключение из HRESULT:0x8001010E (RPC_E_WRONG_THREAD))

Это было полезно?

Решение

Вызовите Freeze() в BitmapSource, и у вас не возникнет этой проблемы (замораживание избавляет от ограничений на потоки, но делает объект неизменяемым)

Другие советы

У меня была именно такая проблема, и мне посчастливилось ее решить.

Краткий ответ:завернуть в WriteableBitmap.За это приходится платить небольшую цену, ты.

Длинный ответ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top