2013-10-31 10 views
7

L'errore generico GDI + durante il salvataggio di una bitmap è ovviamente un problema comune secondo la mia ricerca qui su SO e sul Web. Dato seguente frammento semplificata:Errore generico GDI + salvataggio bitmap creato dalla memoria utilizzando LockBits

byte[] bytes = new byte[2048 * 2048 * 2]; 

for (int i = 0; i < bytes.Length; i++) 
{ 
    // set random or constant pixel data, whatever you want 
} 

Bitmap bmp = new Bitmap(2048, 2048, PixelFormat.Format16bppGrayScale); 
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, 2048, 2048), ImageLockMode.ReadWrite, bmp.PixelFormat); 
System.Runtime.InteropServices.Marshal.Copy(bytes, 0, bmpData.Scan0, 8388608); 
bmp.UnlockBits(bmpData); 
bmp.Save(@"name.bmp"); 

Ciò genera l'errore 0x80004005 generica. Il solito motivo per questo si dice che sia un blocco sui componenti, ma non vedo nulla qui. Sono solo cieco? Il percorso che sto salvando esiste, ovviamente, viene creato solo un file bmp vuoto (0B).

Sfondo: Ricevo i dati dei pixel da un driver della fotocamera che trasferisco su .NET utilizzando un wrapper C++/CLI, pertanto l'oggetto Bitmap sopra riportato viene restituito da una chiamata di funzione. Ma dal momento che questo piccolo esempio non funziona, suppongo che non ci sia nulla di sbagliato nell'adattatore.

Qualsiasi suggerimento è molto apprezzato!

+0

La scala di grigi a 16 bit non è un formato bmp valido? –

+0

Non l'ho considerato, a dire il vero. Passando a 8bpp indicizzati, il file è stato creato senza errori. L'obiettivo finale è salvare l'immagine 16bpp in scala di grigi come PNG, ma sostituendo il precedente con 'bmp.Save (@" name.bmp ", ImageFormat.Png);' non ha funzionato neanche. – simd

+0

Hai provato a specificare ImageFormat.Bmp quando salvi? Vedere questa risposta: http://social.msdn.microsoft.com/Forums/vstudio/en-US/10252c05-c4b6-49dc-b2a3-4c1396e2c3ab/action?threadDisplayName=writing-a-16bit-grayscale-image – Ben

risposta

15
Bitmap bmp = new Bitmap(2048, 2048, PixelFormat.Format16bppGrayScale); 

GDI + eccezioni sono piuttosto scarsa, dovrete poche speranze per diagnosticare i due errori. Il minore è la tua chiamata a Save(), non specifica il ImageFormat che vuoi salvare. L'impostazione predefinita è PNG, non BMP come speravi.

Ma quello principale è PixelFormat.Format16bppGrayScale. Quando GDI + è stato progettato, molto prima che .NET venisse fuori, tutti usavano ancora i CRT invece dei monitor LCD. I CRT erano abbastanza bravi a mostrare una gamma di colori. Sebbene buoni, non c'erano ancora CRT tradizionali che fossero in grado di visualizzare 65536 colori grigi distinti. Il più delle volte è limitato dal DAC nella scheda video, il chip che converte il valore del pixel digitale in un segnale analogico per il CRT. Un DAC in grado di convertire con una precisione di 16 bit a 100 MHz o più non era ancora tecnologicamente fattibile. Microsoft ha scommesso sulla tecnologia di visualizzazione migliorando per rendere possibile un giorno così specificata Format16bppGrayScale come formato pixel che potrebbe essere disponibile un giorno.

Non è successo. Piuttosto il contrario, gli LCD sono significativamente peggiori alla risoluzione dei colori. I pannelli LCD tipici possono risolvere solo 6 bit di un colore anziché gli 8 bit disponibili nel formato pixel. Ottenere una risoluzione cromatica a 16 bit richiederà una significativa svolta tecnologica.

Quindi hanno indovinato e, poiché il formato pixel non è utile, GDI + in realtà non dispone di un codificatore di immagini in grado di scrivere un formato di immagine in scala di grigi a 16 bpp. Kaboom quando provi a salvarlo su disco, indipendentemente dal ImageFormat che scegli.

In scala di grigi 16 bit viene effettivamente utilizzato, l'imaging radiologico utilizza quel formato pixel. Con display molto costosi per renderlo effettivamente utile. Tale apparecchiatura, tuttavia, utilizza sempre un formato immagine personalizzato, DICOM è la scelta abituale. GDI + non ha un codec per questo.

Avrete bisogno di andare a fare shopping per una libreria che supporta il formato di immagine che il cliente desidera. Lead Tools è il gorilla da mille sterline in quel segmento di prodotto.

+0

Grazie per la tua risposta dettagliata, sempre gentile per avere qualche background con la spiegazione. Il punto qui è che le immagini sono usate meno per la visualizzazione, ma dopo l'analisi per il software. Le immagini provengono dalla microscopia time-lapse e le 16 bit ci offrono molte più opzioni rispetto a 8bit. Quindi, se devo andare con una lib extra, WIC dovrebbe funzionare qui (già collegato con esso nell'adattatore della fotocamera), o devo tornare a libpng? – simd

+3

In questo caso, non sei affatto impegnato in alcun formato di immagine supportato. La cosa più intelligente da fare qui è salvare i dati nel tuo formato. Ad esempio, BinaryWriter non può fare nulla. –

+1

I bitmap a 16 bit sono utili anche per dati di intervallo (ad esempio quelli generati da Kinect, ad esempio) – Eponymous

Problemi correlati