2012-05-14 6 views
8

Utilizzo il framework .NET (provato 3.5 & 4.0) per caricare un file .TIFF e salvarlo come .PNG. Mi aspetto due chiamate successive al metodo Save() (utilizzando lo stesso file TIFF) per produrre lo stesso file PNG. I file prodotti sono, tuttavia, "a volte" diversi.Il metodo Image.Save .NET produce risultati non riproducibili su Windows 64 bit

La # codice C indica il problema:

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

Apparirà 'Diff' all'iterazione 8, 32, 33, 73 114, 155, 196 in Windows 64, mentre non visualizza errori su macchine a 32 bit. (Io uso target x86, con target x64, è peggio: diff a iteration 12, 13, 14, 15, ...)

C'è un modo per ottenere un risultato riproducibile da Save()?

un'immagine di esempio si possono trovare su questo FTP site

+0

Ci sono varie impostazioni che vanno nella compressione di un file e potrebbe essere l'ottimizzazione per alcuni fattori in fase di esecuzione. Ad esempio, qualcosa come la dimensione del dizionario potrebbe influenzare la dimensione dell'output compresso, ma produrre comunque gli stessi dati decompressi. Quindi le tue immagini sono sempre le stesse, ma potrebbero essere state ottimizzate in modo leggermente diverso. Probabilmente la costruzione a 64 bit sta dando alcune impostazioni diverse sotto il cofano. Potresti guardare le impostazioni dell'encoder per i sovraccarichi di salvataggio, ma non ho visto nulla di fuori mano che avrebbe reso deterministico l'output compresso. – mafafu

+0

Grazie per il tuo commento. Anch'io supponevo che le immagini dovessero essere uguali in memoria (solo i file .png differiscono). Ma sono arrivato a scrivere una funzione per leggere le immagini come BMP, convertirle in array di byte e - sono diverse (anche se visivamente le immagini non differiscono). Ho anche scoperto che il problema si verifica solo con immagini relativamente grandi (circa 2600x2600 pixel nel mio caso). Ho anche provato con librerie di terze parti come FreeImage - lo stesso problema: deterministico su 32 bit, non su 64 bit. – werner

+1

puoi pubblicare un link a quell'immagine F1.tif? – avs099

risposta

2

non riesco a spiegare perché questo sta accadendo, ma sembra che la messa a punto non-deterministico dei Image oggetti sul filo finalizzatore sta interessando la codifica di immagini su il thread principale. (Image implementa IDisposable, così si dovrebbe chiamare Dispose su di esso per pulire in modo deterministico in su quando hai finito di usarlo,. In caso contrario, sarà finalizzato ad un tempo arbitrario in futuro)

Se cambio il codice di esempio a quanto segue, ottengo gli stessi risultati da ogni chiamata a 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 
} 

si noti che ho trovato un ulteriore stranezza: durante l'esecuzione a 32 bit (x86) costruire su Windows 7 SP1 x64, il primo due chiamate a Save hanno restituito risultati diversi, quindi ogni successiva chiamata a Save ha prodotto la stessa uscita della seconda chiamata. Per superare il test, ho dovuto ripetere le prime due righe (prima del ciclo) per forzare due salvataggi prima di eseguire i controlli di uguaglianza.

+0

Grazie per quello! È un po 'spettrale che la finalizzazione dell'immagine successiva dovrebbe modificarlo, ma la tua soluzione funziona perfettamente per quello che voglio fare. Eccellente! – werner