2012-05-14 14 views
8

Tôi đang sử dụng .NET framework (đã thử 3,5 & 4.0) để tải tệp .TIFF và lưu tệp dưới dạng .PNG. Tôi mong đợi hai cuộc gọi tiếp theo đến phương thức Save() (sử dụng cùng một tệp TIFF) để tạo ra cùng một tệp PNG. Tuy nhiên, các tệp được tạo ra là 'đôi khi' khác nhau.Phương pháp .NET Image.Save tạo ra kết quả không thể tái sản xuất trên Windows 64 bit

C# mã dưới đây trình bày các vấn đề:

Image sourceToConvert = Bitmap.FromFile("c:\\tmp\\F1.tif"); 
sourceToConvert.Save("c:\\tmp\\F1_gen.png", ImageFormat.Png);   

for (int i = 0; i < 100; i++) 
{ 
    sourceToConvert = Bitmap.FromFile("c:\\tmp\\F1.tif"); 
    sourceToConvert.Save("c:\\tmp\\F1_regen.png", ImageFormat.Png); 

    if (!CompareFileBytes("c:\\tmp\\F1_gen.png", "c:\\tmp\\F1_regen.png")) 
     MessageBox.Show("Diff" + i);     
} 

này sẽ hiển thị 'Diff' tại lặp 8, 32, 33, 73 114, 155, 196 trên Windows 64, trong khi nó không hiển thị bất kỳ lỗi trên máy 32 bit. (Tôi sử dụng mục tiêu x86, với mục tiêu x64, nó tệ hơn: khác biệt ở lần lặp 12, 13, 14, 15, ...)

Có cách nào để có được kết quả có thể sao chép từ Save() không?

Một hình ảnh mẫu có thể được tìm thấy trên này FTP site

+0

Có nhiều cài đặt khác nhau đi vào nén tệp và có thể tối ưu hóa một số yếu tố trong thời gian chạy. Ví dụ, một cái gì đó giống như kích thước từ điển có thể ảnh hưởng đến kích thước của đầu ra nén nhưng vẫn mang lại cùng một dữ liệu được giải nén. Vì vậy, hình ảnh của bạn vẫn như cũ, nhưng có thể đã được tối ưu hóa hơi khác nhau. Có lẽ xây dựng đến 64bit là đưa ra một số cài đặt khác nhau bên dưới mui xe. Bạn có thể xem xét các thiết lập bộ mã hóa cho quá tải Lưu, nhưng tôi không thấy bất kỳ thứ gì ngoài tầm tay để làm cho đầu ra nén được xác định. – mafafu

+0

Cảm ơn nhận xét của bạn. Tôi cũng cho rằng các hình ảnh phải giống nhau trong bộ nhớ (chỉ có các tệp .png khác nhau). Nhưng tôi đã đi xa như viết một chức năng để đọc lại các hình ảnh như BMP, chuyển đổi thành mảng byte và - chúng khác nhau (mặc dù hình ảnh không khác nhau). Tôi cũng thấy rằng vấn đề chỉ xảy ra với những hình ảnh tương đối lớn (khoảng 2600x2600 điểm ảnh trong trường hợp của tôi). Tôi cũng đã thử với các thư viện của bên thứ ba như FreeImage - cùng một vấn đề: xác định trên 32 bit, không phải trên 64bit. – werner

+1

bạn có thể gửi một liên kết đến hình ảnh F1.tif đó không? – avs099

Trả lời

2

Tôi không thể giải thích tại sao điều này xảy ra, nhưng có vẻ như quyết toán không xác định của các đối tượng trên Image thread finalizer đang ảnh hưởng đến mã hóa hình ảnh trên chủ đề chính. (Image thực hiện IDisposable, vì vậy bạn nên gọi Dispose vào nó để deterministically sạch nó lên khi bạn đã hoàn tất sử dụng nó;. Nếu không, nó sẽ được hoàn thành vào một thời điểm bất kỳ trong tương lai)

Nếu tôi thay đổi mã ví dụ của bạn để sau, tôi nhận được kết quả tương tự từ tất cả các cuộc gọi đến Save:

using (Image sourceToConvert = Bitmap.FromFile("c:\\tmp\\F1.tif")) 
    sourceToConvert.Save("c:\\tmp\\F1_gen.png", ImageFormat.Png);   

for (int i = 0; i < 100; i++) 
{ 
    using (Image sourceToConvert = Bitmap.FromFile("c:\\tmp\\F1.tif")) 
     sourceToConvert.Save("c:\\tmp\\F1_regen.png", ImageFormat.Png); 

    // files are the same 
} 

Lưu ý rằng tôi đã tìm thấy một kỳ quặc hơn nữa: khi chạy một phiên bản 32-bit (x86) xây dựng trên Windows 7 SP1 x64, các đầu tiên hai cuộc gọi đến Save trả lại các kết quả khác nhau, sau đó mọi cuộc gọi tiếp theo đến Save sản xuất cùng một đầu ra như cuộc gọi thứ hai. Để thực hiện kiểm tra, tôi phải lặp lại hai dòng đầu tiên (trước vòng lặp) để buộc hai lần lưu trước khi thực hiện kiểm tra bình đẳng.

+0

Cảm ơn vì điều đó! Một chút ma quái của nó mà hoàn thiện hình ảnh sau này nên sửa đổi nó, nhưng giải pháp của bạn hoạt động hoàn hảo cho những gì tôi muốn làm. Xuất sắc! – werner

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