2011-09-10 6 views
12

Ho diversi (~ 2 GB) file RGB 24bpp raw su disco rigido. Ora voglio recuperarne una parte e ridimensionarla alla dimensione desiderata.
(le uniche scale consentite sono 1, 1/2, 1/4, 1/8, ..., 1/256)C# Ottenere i dati dei pixel in modo efficiente da System.Drawing.Bitmap

Quindi sto attualmente leggendo ogni riga dal rettangolo di interesse in un array , che mi lascia con una bitmap che ha altezza corretta ma larghezza errata.

Come passaggio successivo sto creando un bitmap dall'array appena creato.
L'operazione viene eseguita utilizzando un puntatore in modo da evitare la copia dei dati coinvolti.
Avanti Chiamerò GetThumbnailImage in Bitmap, che crea una nuova bitmap con le dimensioni corrette.

Ora voglio restituire i dati grezzi dei pixel (come un array di byte) della bitmap appena creata. Ma per riuscirci attualmente sto copiando i dati usando LockBit in un nuovo array.

Quindi la mia domanda è: C'è un modo per ottenere i dati dei pixel da un bitmap in un array di byte senza copiarli?

Qualcosa di simile:

var bitmapData = scaledBitmap.LockBits(...) 
byte[] rawBitmapData = (byte[])bitmapData.Scan0.ToPointer() 
scaledBitmap.UnlockBits(bitmapData) 
return rawBitmapData 

Sono ben consapevole che questo non funziona, è solo un esempio di quello che fondamentalmente voglio raggiungere.

+0

per funzionare, invece di non sicuro {} void * a byte [], prova IntPtr ptr = bitmapData.Scan0; int bytes = Math.Abs ​​(bitmapData.Stride) * bitmapData.Height; raw = new byte [byte]; Marshal.Copy (ptr, raw, 0, byte); ritorno raw; // byte [] – antonio

risposta

15

Penso che questa sia la soluzione migliore.

var bitmapData = scaledBitmap.LockBits(...); 
var length = bitmapData.Stride * bitmapData.Height; 

byte[] bytes = new byte[length]; 

// Copy bitmap to byte[] 
Marshal.Copy(bitmapData.Scan0, bytes, 0, length); 
scaledBitmap.UnlockBits(bitmapData); 

dovete copiarlo, se si vuole un passaggio intorno ad un byte [].

Non è necessario eliminare i byte allocati, ma è necessario eliminare l'oggetto Bitmap originale quando viene eseguito mentre implementa IDisposable.

+0

Non esattamente la risposta che speravo, ma l'utilizzo di Marshal.Copy lo rende molto più bello rispetto alla copia di un intero per intero. Grazie – Arokh