2010-01-24 29 views
5

Tôi là người mới bắt đầu với WPF và đang thử một dự án nhà để làm quen với công nghệ này. Tôi có một hình thức đơn giản, nơi người dùng chọn một tệp hình ảnh, sau đó tôi hiển thị dữ liệu EXIF ​​cùng với hình thu nhỏ của hình ảnh. Điều này làm việc tốt nhưng khi tôi chọn một tập tin ảnh RAW (~ 9 MB) có thể có một chút chậm trễ trong khi ngón tay cái tải, vì vậy tôi nghĩ tôi có thể sử dụng BackgroundWorker để giải mã hình ảnh và người dùng có thể xem dữ liệu EXIF, sau đó khi hình ảnh đã được giải mã, nó sẽ được hiển thị.Vấn đề WPF/BackgroundWorker và BitmapSource

Đối tượng BitmapSource được khai báo trong các phương pháp 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; 
}; 

vấn đề mà tôi đang chạy vào là khi tôi cố gắng để thiết lập các nguồn kiểm soát hình ảnh của tôi trong phương pháp RunWorkerCompleted tôi nhận được một lỗi bởi vì đối tượng được sở hữu bởi một chủ đề khác.

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

tôi đã cố gắng sử dụng phương pháp imgThumb.Dispatcher.BeginInvoke() để thiết lập các nguồn nhưng điều này đã không làm việc một trong hai, tôi đoán đó là vì đó là args.Result được sở hữu bởi chủ đề khác, và không phải là imgThumb? Làm thế nào tôi có thể nhận được vòng này?

Có thể là tôi đã mã hóa Dispatcher của tôi sai (sau đây là từ bộ nhớ, tôi đã xóa những gì tôi đã có).

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

Bất kỳ đề xuất hoặc ý tưởng nào đều được hoan nghênh.

Cập nhật

Thay đổi phương pháp DoWork tôi để sử dụng chứ không phải là BitmapCreateOptions.None .DelayCreation nhưng bây giờ tôi nhận được lỗi sau khi tải file RAW (file Canon .CR2 là tất cả tôi đã thử nghiệm cho đến nay), các mã hoạt động tốt cho jpg. Đây có phải là vấn đề với Canon Codec I được cài đặt để cho phép tôi hiển thị các tệp RAW không?

Ứng dụng được gọi là giao diện đã được khắc phục cho một luồng khác nhau . (Ngoại lệ từ HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

Trả lời

8

Gọi Freeze() trên BitmapSource và bạn sẽ không phải vấn đề này (Freezing được thoát khỏi những hạn chế luồng, nhưng làm cho đối tượng không thay đổi)

+0

Tôi đã thêm lệnh Freeze() trong phương thức DoWork của tôi, ngay sau khi đặt giá trị BitmapSource. Sau đó tôi thêm dòng sau vào phương thức RunWorkerCompleted: BitmapSource xx = args.Result; cho tôi lỗi tương tự như trước. Tôi thiếu bất cứ điều gì rõ ràng? Tôi đã lấy ra bất kỳ mã nào bằng cách sử dụng Dispatcher. – Fermin

+0

Tôi đã từng là một kẻ ngốc nghếch nhưng bây giờ có một sự khác biệt. lỗi, câu hỏi được cập nhật. – Fermin

+0

Thậm chí sau nhiều năm. CẢM ƠN NHIỀU. đang tìm kiếm điều này trên mạng – Kulpemovitz

2

Tôi đã có chính xác các vấn đề mẫu và đã may mắn để giải quyết nó.

Câu trả lời ngắn gọn: gói trong WriteableBitmap. Điều đó đến với một mức giá nhỏ, bạn.

Long answer.

+0

Đối với trường hợp của tôi, đây là giải pháp duy nhất hoạt động. Tôi cần thiết để nuôi một BitmapFrame vào một TransformedBitmap. Không có quyền kiểm soát đối với chuỗi mà BitmapFrame được tạo ra vì nó được cung cấp bởi một thư viện (và thuộc tính Dispatcher của BitmapFrame là null).Ngay cả truy vấn tài sản CanFreeze cũng gây ra một ngoại lệ. Tôi có hai lựa chọn: sửa chữa lớn mã nguồn của tôi và những người khác, hoặc sử dụng WriteableBitmap. Đoán xem tôi chọn cái nào ... – elgonzo

Các vấn đề liên quan