2013-03-07 13 views
12

Ho un byte[] che rappresenta i dati grezzi di un'immagine. Vorrei convertirlo in un BitmapImage.Come posso convertire il byte [] in BitmapImage?

Ho provato diversi esempi che ho trovato, ma ho continuato a ottenere la seguente eccezione

"è stato trovato alcun componente di imaging adatto per completare questa operazione."

Penso che sia perché il mio byte[] non rappresenta in realtà un'immagine ma solo i bit grezzi. quindi la mia domanda è come detto sopra è come convertire un byte [] di bit grezzi in uno BitmapImage.

risposta

8

Quando l'array di byte contiene i dati di pixel grezzi di una bitmap, è possibile creare un BitmapSource (che è la classe base di BitmapImage) mediante il metodo statico BitmapSource.Create.

Tuttavia, è necessario specificare alcuni parametri della bitmap. È necessario conoscere in anticipo la larghezza e l'altezza e anche il PixelFormat del buffer.

byte[] buffer = ...; 

var width = 100; // for example 
var height = 100; // for example 
var dpiX = 96d; 
var dpiY = 96d; 
var pixelFormat = PixelFormats.Pbgra32; // for example 
var bytesPerPixel = (pixelFormat.BitsPerPixel + 7)/8; 
var stride = bytesPerPixel * width; 

var bitmap = BitmapSource.Create(width, height, dpiX, dpiY, 
           pixelFormat, null, buffer, stride); 
+0

Su Windows Phone 8, quanto sopra non funziona poiché BitmapSource non supporta l'opzione di creazione. Vuoi sapere qualche alternativa? – vishal

+1

@vishal Dovresti usare un [WriteableBitmap] (http://msdn.microsoft.com/it-it/library/windows/apps/windows.ui.xaml.media.imaging.writeablebitmap.aspx). – Clemens

+0

Grazie. Ho già provato questa opzione ora: http://stackoverflow.com/questions/17714662/convert-int-to-byte-type-pointer-in-c-sharp/17715106?noredirect=1#17715106 – vishal

-1

Creare un MemoryStream dai byte non elaborati e passarlo nel costruttore di Bitmap.

Ti piace questa:

MemoryStream stream = new  MemoryStream(bytes); 
Bitmap image = new Bitmap(stream); 
+0

Si sta facendo riferimento a 'System.Drawing.Bitmap', che non è WPF. – Clemens

11
public static BitmapImage LoadFromBytes(byte[] bytes) 
{ 
    using (var stream = new MemoryStream(bytes)) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 
     var image = new BitmapImage(); 
     image.BeginInit(); 
     image.StreamSource = stream; 
     image.EndInit(); 

     return image; 
    } 
} 
+0

In realtà, ho provato questo, ma non ha funzionato fino a quando non ho aggiunto le righe dall'OP su questa domanda: http://stackoverflow.com/questions/35831893/bitmapimage-to-byte-and-reverse: 'image. CreateOptions = BitmapCreateOptions.PreservePixelFormat; image.CacheOption = BitmapCacheOption.OnLoad; '- Altrimenti ho appena avuto un'area di immagine vuota. – vapcguy

0

mi sono imbattuto in questo stesso errore, ma era perché la mia matrice non si stava riempito con i dati effettivi. Avevo una serie di byte uguale alla lunghezza che si supponeva fosse, ma i valori erano tutti ancora 0 - non erano stati scritti!

Il mio problema particolare - e sospetto per gli altri che arrivano a questa domanda, è stato a causa del parametro OracleBlob. Non pensavo di averne bisogno, e ho pensato che potevo semplicemente fare qualcosa del tipo:

DataSet ds = new DataSet(); 
OracleCommand cmd = new OracleCommand(strQuery, conn); 
OracleDataAdapter oraAdpt = new OracleDataAdapter(cmd); 
oraAdpt.Fill(ds) 

if (ds.Tables[0].Rows.Count > 0) 
{ 
    byte[] myArray = (bytes)ds.Tables[0]["MY_BLOB_COLUMN"]; 
} 

Quanto sbagliavo! Per ottenere effettivamente i veri byte in quel blob, avevo bisogno di leggere effettivamente quel risultato in un oggetto OracleBlob. Invece di riempire un set di dati/DataTable, ho fatto questo:

OracleBlob oBlob = null; 
byte[] myArray = null; 
OracleCommand cmd = new OracleCommand(strQuery, conn); 
OracleDataReader result = cmd.ExecuteReader(); 
result.Read(); 

if (result.HasRows) 
{ 
    oBlob = result.GetOracleBlob(0); 
    myArray = new byte[oBlob.Length]; 
    oBlob.Read(array, 0, Convert.ToInt32(myArray.Length)); 
    oBlob.Erase(); 
    oBlob.Close(); 
    oBlob.Dispose(); 
} 

Poi, ho potuto prendere myArray e fare questo:

if (myArray != null) 
{ 
    if (myArray.Length > 0) 
    { 
     MyImage.Source = LoadBitmapFromBytes(myArray); 
    } 
} 

E la mia rivista LoadBitmapFromBytes funzione dal altra risposta:

public static BitmapImage LoadBitmapFromBytes(byte[] bytes) 
{ 
    var image = new BitmapImage(); 
    using (var stream = new MemoryStream(bytes)) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 
     image.BeginInit(); 
     image.StreamSource = stream; 
     image.CreateOptions = BitmapCreateOptions.PreservePixelFormat; 
     image.CacheOption = BitmapCacheOption.OnLoad; 
     image.UriSource = null; 
     image.EndInit(); 
    } 

    return image; 
} 
Problemi correlati