Pergunta

Sou iniciante no WPF e estou tentando um projeto doméstico para me familiarizar com a tecnologia.Eu tenho um formulário simples onde o usuário seleciona um arquivo de imagem e, em seguida, exibo os dados EXIF ​​junto com uma miniatura da imagem.Isso está funcionando bem, mas quando eu seleciono um arquivo de imagem RAW (~9 MB), pode haver um pequeno atraso enquanto o polegar carrega, então pensei em usar o BackgroundWorker para decodificar a imagem e o usuário pode visualizar os dados EXIF, então quando a imagem for decodificada, ela será exibida.

O objeto BitmapSource é declarado no método 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;
};

o problema que estou enfrentando é quando tento definir a origem do meu controle de imagem no método RunWorkerCompleted, recebo um erro porque o objeto pertence a outro thread.

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

Eu tentei usar o imgThumb.Dispatcher.BeginInvoke() método para definir a fonte, mas também não funcionou, acho que é porque é o args.Result que pertence a outro thread, e não ao imgThumb?Como posso contornar isso?

Pode ser que eu estivesse codificando meu Dispatcher de forma errada (o seguinte é de memória, apaguei o que tinha).

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

Quaisquer sugestões ou ideias são bem-vindas.

Atualizar

Alterei meu método DoWork para usar BitmapCreateOptions.None em vez de .DelayCreation, mas agora recebo o seguinte erro ao carregar arquivos RAW (os arquivos Canon .CR2 são tudo que testei até o momento), o código funciona bem para jpg.Isso poderia ser um problema com o Canon Codec que instalei para permitir a exibição dos arquivos RAW?

O aplicativo chamou uma interface que foi organizada para um encadeamento diferente.(Exceção de HRESULT:0x8001010E (RPC_E_WRONG_THREAD))

Foi útil?

Solução

Chame Freeze() no BitmapSource e você não terá esse problema (o congelamento elimina as restrições de threading, mas torna o objeto imutável)

Outras dicas

Eu tive exatamente o problema da amostra e tive sorte de resolvê-lo.

Resposta curta:embrulhar em WriteableBitmap.Isso tem um pequeno preço, você.

Resposta longa.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top