2010-02-19 5 views
5

Prima, quando stavo usando win32, ho usato FreeImage per caricare e salvare bitmap di profondità di bit superiore a 8 bit. Sono tutte le immagini con cui lavoro, dal momento che sto facendo imaging medico, e prima che qualcuno dica qualcosa, sì, io e i miei clienti abbiamo speso un sacco di soldi su monitor ad alta luminosità e contrasto elevato con 11 o 12 bit di gamma dinamica . Infatti, se sei curioso, lo requirements by the ACR for running mammography include un monitor con almeno 10 bit di gamma dinamica.Come posso salvare/caricare un'immagine a 16 bit in .net x64?

Ho appena passato a x64 per i sovraccarichi di memoria e per ottenere tutto il mio sviluppo su una piattaforma e modalità di compilazione. Preferirei non tornare a vincere32, ei miei clienti sono proprio lì con me (e davvero costringendo il cambiamento). FreeImage non si compila su finestre a 64 bit; ha una direttiva _asm nel codice che il compilatore non può gestire.

Ho pensato di provare il supporto nativo .NET nelle classi Microsoft. Per farla breve: non funzionano e falliscono con messaggi di errore molto limitati. Sospetto che sia perché Microsoft ancora non supporta la classe Format16bppGrayScale.

Forse c'è un problema nel mio codice. Ecco il mio codice per la scrittura:

Bitmap theBitmap = new Bitmap(inImage.XSize, inImage.YSize, PixelFormat.Format16bppGrayScale); 

//have to go with lockbits 
Rectangle rect = new Rectangle(0, 0, theBitmap.Width, theBitmap.Height); 
System.Drawing.Imaging.BitmapData bmpData = 
    theBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, 
    PixelFormat.Format16bppGrayScale); 
IntPtr ptr = bmpData.Scan0; 
int theByteSize = theBitmap.Width * theBitmap.Height *2; 
byte[] theByteBuffer = new byte[theByteSize]; 
System.Buffer.BlockCopy(inImage.Data, 0, theByteBuffer, 0, theByteSize); 
System.Runtime.InteropServices.Marshal.Copy(theByteBuffer, 0, ptr, theByteSize); 
theBitmap.UnlockBits(bmpData); 

theBitmap.Save(inDirectory + "\\" + inName); 
theBitmap.Dispose(); 

Questo codice si blocca il programma con

An unhandled exception of type 
'System.Runtime.InteropServices.ExternalException' occurred in 
System.Drawing.dll 

Additional information: A generic error occurred in GDI+. 

interessante, soprattutto perché non ho mai voglia di disegnare questa immagine per la schermata come questa (anche se sarebbe bello!) , ma voglio solo usare la funzionalità di salvataggio/caricamento. L'immagine venga scritto su disco (anche se il programma si blocca) e il seguente codice di lettura si blocca anche il programma:

Bitmap theBitmap = new Bitmap(theCompleteName, false); 
ushort[] theData = new ushort[theBitmap.Width * theBitmap.Height]; 
int x, y; 

switch (theBitmap.PixelFormat) 
{ 
    case PixelFormat.Format16bppGrayScale: 
     //have to go with lockbits 
     {   
      Rectangle rect = new Rectangle(0, 0, theBitmap.Width, theBitmap.Height); 
      System.Drawing.Imaging.BitmapData bmpData = 
       theBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, 
       PixelFormat.Format16bppGrayScale); 
      IntPtr ptr = bmpData.Scan0;//scanline approach left over from FreeImage 

      for (y = 0; y < theBitmap.Height; ++y){ 
       byte[] scanline = new byte[theBitmap.Width*2]; 
       System.Runtime.InteropServices.Marshal.Copy(ptr, scanline, y * theBitmap.Width * 2, theBitmap.Width * 2); 
       System.Buffer.BlockCopy(scanline, 0, theData, y * theBitmap.Width * 2, theBitmap.Width * 2); 
      } 
      theBitmap.UnlockBits(bmpData); 
     } 
     break; 
    //for colors, just take the red and call it a day 


    case PixelFormat.Format24bppRgb: 
    case PixelFormat.Format32bppArgb://really stupid reading code, always works 
     for (y = 0; y < theBitmap.Height; ++y) { 
      for (x = 0; x < theBitmap.Width; ++x) { 
       theData[y * theBitmap.Width + x] = (byte)(theBitmap.GetPixel(x, y).R); 
      } 
     } 
     break; 
} 
theNewImage = new ImageContainer(theData, theBitmap.Width, theBitmap.Height, inName, inAssessmentID); 
theBitmap.Dispose();//not needed, anymore 

Questo codice si blocca il programma con l'errore:

An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll 

Additional information: Parameter is not valid. 

Questi risultati dimmi che Microsoft non ha ancora corretto la porzione Format16bppGrayScale dell'enumerazione PixelFormat. È un peccato.

Quindi, cosa posso utilizzare per caricare e salvare immagini in scala di grigi a 16 bit su x64 con .NET?

(MODIFICA: devo aggiungere che mentre posso salvare le immagini DICOM, ho bisogno di eseguire esperimenti su dati non paziente per verificare che gli algoritmi siano validi, e così via. DICOM richiede un set di UID e altro campi che sono eccessivi per ciò di cui ho bisogno, ho solo bisogno di immagini, e non di dati del paziente, al momento).

risposta

3

FreeImage può essere compilato per x64. Seguendo le istruzioni here è possibile aggirare la direttiva _asm. C'è anche una dll compilata a 64 bit nella parte inferiore della pagina.

L'ultima versione (3.15.1) contiene già questa correzione. Ho scelto la distribuzione dei sorgenti per provare (sono curioso di usare FreeImage nel mio progetto) e la piattaforma x64 compila subito.

+0

Hai ragione-- al momento, il progetto freeimage viene compilato per x64. Grazie per segnalarlo! – mmr

0

Non rispondo alla domanda, ma in precedenza ho utilizzato il componente ImageDraw venduto da Neodnyamic e lo consiglierei (e lo userei di nuovo). Non è gratuito, ma vale la pena un piccolo investimento.

+0

hrm. Sembra che ImageDraw utilizzi GDI +, il che significa che dovrebbe avere esattamente gli stessi errori di quello che sto ottenendo ora, giusto? – mmr

+0

Scarica la versione di prova e scoprilo.Dalla memoria il componente è stato acquistato a causa dei problemi con GDI +. – Kane

Problemi correlati