2009-02-12 17 views
5

Khi tôi cố gắng lưu một BitmapSource mà tôi đã tải trước đó, một đoạn mã khác sẽ không thể mở được.Tải một BitmapSource và lưu sử dụng cùng tên trong WPF -> IOException

Nếu tôi chỉ lưu tải không có whithout trước đó, mọi thứ hoạt động tốt.

Mã tải:

BitmapImage image = new BitmapImage(); 

image.BeginInit(); 
image.UriSource = uri; 

if (decodePixelWidth > 0) 
image.DecodePixelWidth = decodePixelWidth; 

image.EndInit(); 

mã tiết kiệm:

using (FileStream fileStream = new FileStream(Directory + "\\" + FileName + ".jpg", FileMode.Create)) 
{ 
    JpegBitmapEncoder encoder = new JpegBitmapEncoder(); 
    encoder.Frames.Add(BitmapFrame.Create((BitmapImage)image)); 
    encoder.QualityLevel = 100; 
    encoder.Save(fileStream); 
} 

Nó có vẻ như sau khi tải dữ liệu hình ảnh, tập tin vẫn còn bị khóa một không bao giờ có thể được ghi đè trong khi ứng dụng đã mở nó vẫn đang chạy. Bất kỳ ý tưởng làm thế nào để giải quyết điều này? Cảm ơn rất nhiều cho bất kỳ giải pháp.

Trả lời

9

Lấy cảm hứng từ các nhận xét tôi nhận được về vấn đề này, tôi giải quyết được vấn đề bằng cách đọc tất cả các byte vào bộ nhớ và sử dụng nó làm Sreamsource của BitmapImage.

Cái này hoạt động hoàn hảo:

if (File.Exists(filePath)) 
{ 
    MemoryStream memoryStream = new MemoryStream(); 

    byte[] fileBytes = File.ReadAllBytes(filePath); 
    memoryStream.Write(fileBytes, 0, fileBytes.Length); 
    memoryStream.Position = 0; 

    image.BeginInit(); 
    image.StreamSource = memoryStream; 

    if (decodePixelWidth > 0) 
     image.DecodePixelWidth = decodePixelWidth; 

    image.EndInit(); 
} 
+0

Bạn lấy ý kiến ​​của người khác, không upvote bất cứ ai, tạo ra một giải pháp phái sinh mà bạn đăng như là một câu trả lời, và bạn đã cho mình bỏ phiếu Poster-Approved-Answer? – hughdbrown

+15

Tôi mới dùng stackoverflow. Như bạn thấy. Do đó tôi không thể cho phép những người khác cho đến khi tôi có danh tiếng là 15. Và vì những người khác vui lòng đưa ra những gợi ý tốt, nhưng không có giải pháp thực sự cho những người có cùng một vấn đề, tôi đã tự cung cấp câu trả lời như một kết quả nghiên cứu của chính tôi. Vấn đề? – sdippl

0

Bây giờ tôi không chắc chắn nếu điều này có thể được áp dụng cho BitmapImage nhưng tôi đã có một vấn đề rất giống với tiết kiệm một hình ảnh sửa đổi để các tập tin gốc trong GDI + here

Phương pháp tải hình ảnh từ tập tin giữ một khóa mở trên tệp cho đến khi đối tượng hình ảnh được xử lý.

Có thể đó là điều tương tự với bitmapimage.urisource. Nếu không chơi xung quanh bạn có thể sao chép hình ảnh trong bộ nhớ và vứt bỏ bản gốc do đó mở khóa các tập tin?

3

Thêm dòng sau vào mã tải của bạn:

image.CacheOption = BitmapCacheOption.OnLoad; 

này sẽ được tải mở tập tin, đọc nó vào bộ nhớ, và đóng tất cả trong image.EndInit. Giá trị mặc định là BitmapCacheOption.Default có hành vi kỳ lạ khi mở tệp, đọc tệp đó vào bộ nhớ nhưng chưa đóng nó trong thời gian image.EndInit.

+1

này hoạt động, nhưng bạn cũng cần phải sử dụng BitmapCreateOptions.IgnoreImageCache trong trường hợp bạn tạo một BitmapImage mới sử dụng cùng một đường dẫn sau này trong tiến trình. Điều này là do BitmapImage sẽ lưu trữ dữ liệu hình ảnh trên các phiên bản của lớp BitmapImage. – manu08

+0

@ manu08: nếu chỉ có tôi có thể upvote bạn cho điều này bằng cách nào đó. Tôi đã dành một thời gian dài nhìn quanh và không thể tìm ra giải pháp cho vấn đề của mình. Trong khi viết câu hỏi SO của riêng tôi, tôi đã may mắn và đã xảy ra để tìm bình luận của bạn, và nó đã được chính xác những gì tôi cần! – Dave

0

Đặt CacheOption thành BitmapCacheOption.OnLoad, sẽ không giải quyết được sự cố của bạn. Tôi nghĩ rằng có một lỗi, nhưng tôi đã có cùng một vấn đề. Cuối cùng tôi tải hình ảnh của tôi vào một dòng bộ nhớ và xử lý BitmapImage trước khi lưu hình ảnh vào tập tin.

+0

Thực ra nó hoạt động tốt cho tôi. Bạn phải tạo BitmapImage, gọi BeginInit() sau đó thiết lập CacheOption, sau đó thiết lập UriSource sau đó gọi EndInit(). –

7

Dưới đây là một giải pháp, dựa trên mã nạp bản gốc:

var image = new BitmapImage(); 
image.BeginInit(); 

// overwrite cache if already exists, to refresh image 
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache; 
// load into memory and unlock file 
image.CacheOption = BitmapCacheOption.OnLoad; 

image.UriSource = uri; 
if (decodePixelWidth > 0) image.DecodePixelWidth = decodePixelWidth; 
image.EndInit(); 
Các vấn đề liên quan