2009-03-24 7 views
8

sto catturare le immagini da un sensore fotocamera intelligente e ricevere l'array di byte dalla telecamera attraverso la programmazione socket (NET è il cliente, la macchina fotografica è il server).Image.FromStream() restituisce un'eccezione Argomento non valido

Il problema è che ottengo un'eccezione System.InvalidArgument in fase di esecuzione.

private Image byteArrayToImage(byte[] byteArray) 
{ 
    if(byteArray != null) 
    { 
     MemoryStream ms = new MemoryStream(byteArray); 
     return Image.FromStream(ms, false, false); 
     /*last argument is supposed to turn Image data validation off*/ 
    } 
    return null; 
} 

Ho cercato questo problema in molti forum e ho provato i suggerimenti dati da molti esperti ma nulla ha aiutato.

Non penso ci sia alcun problema con l'array di byte in quanto tale perché quando alimento lo stesso array di byte nella mia applicazione client MFC VC++, ottengo l'immagine. Ma questo non funziona in qualche modo in C# .NET.

Qualcuno può aiutarmi?

PS:

Altri metodi ho provato ad eseguire la stessa operazione sono:

1.

private Image byteArrayToImage(byte[] byteArray) 
{ 
    if(byteArray != null) 
    { 
     MemoryStream ms = new MemoryStream(); 
     ms.Write(byteArray, 0, byteArray.Length); 
     ms.Position = 0; 
     return Image.FromStream(ms, false, false); 
    } 
    return null; 
} 

2.

private Image byteArrayToImage(byte[] byteArray) 
{ 
    if(byteArray != null) 
    { 
     TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap)); 
     Bitmap b = (Bitmap)tc.ConvertFrom(byteArray); 
     return b; 
    } 
    return null; 
} 

Nessuno dei metodi di cui sopra lavorato. Gentilmente aiuto.

+0

Che cosa succede se è sufficiente scrivere il ByteArray in un file su disco? Il file è in grado di aprirsi con qualcosa come Photoshop? – Chris

+1

hai risolto? Ho lo stesso problema – robob

risposta

1

System.InvalidArgument significa Il flusso non ha un formato di immagine valido, ossia un tipo di immagine non supportato.

+1

Ciao, Grazie per la risposta. Ma come mai lo stesso array di byte funziona nella mia applicazione VFC++ MFC? Inoltre è possibile verificare la validità dei dati dell'immagine del mio array di byte? Arvind K –

0

Ho avuto lo stesso problema in passato ed è stato causato da una perdita all'interno delle librerie di Windows GDI, che è quello che utilizza 'bitmap'. Se questo dovesse accadere tutto il tempo per te allora probabilmente non è correlato, comunque.

+0

Ciao Chris, Grazie per la risposta. Mi succede ogni volta che eseguo il codice. –

3

Sto indovinando che qualcosa sta andando storto quando si riceve il file dal server. Forse stai ottenendo solo una parte del file prima di provare a convertirlo in un Image? Sei sicuro è esattamente lo stesso array di byte che stai alimentando con l'applicazione C++?

Provare a salvare il flusso su un file e vedere cosa si ottiene. Potresti essere in grado di scoprire alcuni indizi lì.

È inoltre possibile aggiungere un punto di interruzione e confrontare manualmente alcuni dei byte nella matrice di byte di quello che si suppone di essere (se si sa che).


Modifica: Sembra che non ci sia niente di sbagliato nel ricevere i dati. Il problema è che è in formato raw (non in un formato che sia compreso in Image.FromStream). Il Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr) constructor potrebbe essere utile qui. In alternativa, è possibile creare la bitmap vuota e selezionarla manualmente dai dati non elaborati.

+0

Ciao, Ho provato a salvare l'immagine in un file jpg, bmp ma non riesco a ottenere l'immagine nel file. Che cosa è sconcertante è che è con lo stesso array di byte che sono in grado di visualizzare l'immagine nella mia applicazione MFC VC++. –

+0

Ecco perché non sono così sicuro che sia lo stesso array di byte. Le dimensioni dei file sono le stesse? –

+0

L'applicazione VC++ visualizza immagini in diretta dalla telecamera e quindi ciò che ho fatto è stato scrivere l'array di byte in un file txt. Allo stesso modo, dalla mia app. NET ho scritto l'array di byte in un file e poi ho confrontato questi due file. Trovo che tutti i valori sono pieni e sono più o meno gli stessi. –

3

Ho avuto questo problema quando si fa questo:

MemoryStream stream = new MemoryStream(); 
screenshot.Save(stream, ImageFormat.Png); 
byte[] bytes = new byte[stream.Length]; 
stream.Save(bytes, 0, steam.Length); 

Con le ultime 2 righe che sono il problema.Ho riparato in questo modo:

MemoryStream stream = new MemoryStream(); 
screenshot.Save(stream, ImageFormat.Png); 
byte[] bytes = stream.ToArray(); 

E poi questo ha funzionato:

MemoryStream stream = new MemoryStream(bytes); 
var newImage = System.Drawing.Image.FromStream(stream); 
stream.Dispose(); 
4

Forse l'immagine è incorporato in un campo OLE e si deve prendere in considerazione l'intestazione OLE 88 byte, più carico utile:

byteBlobData = (Byte[]) reader.GetValue(0); 
stream = new MemoryStream(byteBlobData, 88, byteBlobData.Length - 88); 
img = Image.FromStream(stream); 
+0

Nel mio caso, ho solo dovuto "rimuovere" 8 byte. nuovo MemoryStream (byteBlobData, 8, byteBlobData.Length - 8); – iwhp

+3

Come hai potuto sapere che era lungo 8 bit? – C4u

7

Image.FromStream() prevede uno stream che contiene SOLO un'immagine!

Si resetta lo stream.Position a 0. Sono avete un flusso che contiene più immagini o altre cose, è necessario leggere i dati di immagine in un array di byte e per inizializzare un MemoryStream con quel:

Image.FromStream(new MemoryStream(myImageByteArray));

il MemoryStream deve rimanere aperto fino a quando l'immagine è in uso.

Lo so anche io. :)

0

questo codice sta lavorando

 string query="SELECT * from gym_member where Registration_No ='" + textBox9.Text + "'"; 

     command = new SqlCommand(query,con); 
     ad = new SqlDataAdapter(command); 
     DataTable dt = new DataTable(); 
     ad.Fill(dt); 
     textBox1.Text = dt.Rows[0][1].ToString(); 
     textBox2.Text = dt.Rows[0][2].ToString(); 
     byte[] img = (byte[])dt.Rows[0][18]; 
     MemoryStream ms = new MemoryStream(img); 

     pictureBox1.Image = Image.FromStream(ms); 
     ms.Dispose(); 
1

Prova questa:

public Image byteArrayToImage(byte[] item) 
{   
    Image img=Image.FromStream(new MemoryStream(item)); 
    img.Save(Response.OutputStream, ImageFormat.Gif); 
    return img; 
} 

Speranza che aiuta!

0

provare ad usare qualcosa di simile a ciò che viene descritto qui https://social.msdn.microsoft.com/Forums/vstudio/en-US/de9ee1c9-16d3-4422-a99f-e863041e4c1d/reading-raw-rgba-data-into-a-bitmap

Image ImageFromRawBgraArray(
    byte[] arr, 
    int charWidth, int charHeight, 
    int widthInChars, 
    PixelFormat pixelFormat) 
{ 
    var output = new Bitmap(width, height, pixelFormat); 
    var rect = new Rectangle(0, 0, width, height); 
    var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat); 

    // Row-by-row copy 
    var arrRowLength = width * Image.GetPixelFormatSize(output.PixelFormat)/8; 
    var ptr = bmpData.Scan0; 
    for (var i = 0; i < height; i++) 
    { 
     Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength); 
     ptr += bmpData.Stride; 
    } 

    output.UnlockBits(bmpData); 
    return output; 
}