2009-03-24 7 views
8

Je capture des images à partir d'un imageur de caméra intelligente et je reçois le tableau d'octets de la caméra via la programmation de socket (l'application .NET est le client, la caméra est le serveur).La méthode Image.FromStream() renvoie Invalid Argument exception

Le problème est que j'obtiens une exception System.InvalidArgument à l'exécution. J'ai cherché ce problème dans de nombreux forums et essayé les suggestions données par de nombreux experts, mais rien n'a aidé.

Je ne pense pas qu'il y ait un problème avec le tableau d'octets en tant que tel parce que lorsque je charge le même tableau d'octets dans mon application client VC++ MFC, j'obtiens l'image. Mais cela ne fonctionne pas en C# .NET.

Quelqu'un peut-il m'aider?

PS:

D'autres méthodes que j'ai essayé d'accomplir la même tâche sont:

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; 
} 

Aucune des méthodes ci-dessus travaillé. Aide aimablement.

+0

Qu'est-ce qui se passe si vous écrivez simplement le bytearray dans un fichier sur le disque? Le fichier est-il ouvert avec quelque chose comme photoshop? – Chris

+1

l'avez-vous résolu? J'ai le même problème – robob

Répondre

1

System.InvalidArgument signifie que le flux n'a pas un format d'image valide, c'est-à-dire un type d'image qui n'est pas supporté.

+1

Bonjour, Merci pour la réponse. Mais comment le même tableau d'octets fonctionne-t-il dans mon application VC++ MFC? Existe-t-il un moyen de vérifier la validité de mes données d'image de tableau d'octets? Arvind K –

0

J'ai eu le même problème dans le passé et il a été causé par une fuite dans les bibliothèques GDI de Windows, ce que Bitmap utilise. Si cela arrive tout le temps pour vous, c'est probablement sans rapport.

+0

Bonjour Chris, Merci pour la réponse. Il m'arrive à chaque fois que je cours le code. –

3

Je suppose que quelque chose ne va pas lorsque je reçois le fichier du serveur. Peut-être que vous obtenez seulement une partie du fichier avant d'essayer de le convertir en Image? Êtes-vous sûr c'est exactement le même tableau d'octets que vous alimentez l'application C++?

Essayez d'enregistrer le flux dans un fichier et voyez ce que vous obtenez. Vous pourriez être en mesure de découvrir quelques indices là-bas.

Vous pouvez également ajouter un point d'arrêt et comparer manuellement certains des octets du tableau d'octets à ce qu'ils sont censés être (si vous le savez).


Modifier: Il semble qu'il n'y ait rien de mal à recevoir les données. Le problème est que c'est dans le format brut (pas un format que Image.FromStream comprend). Le Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr) constructor peut être utile ici. Ou, vous pouvez créer le bitmap vide et le blt manuellement à partir des données brutes.

+0

Bonjour, J'ai essayé d'enregistrer l'image dans un fichier jpg, bmp mais je n'ai pas l'image dans le fichier. Ce qui est curieux, c'est que c'est avec le même tableau d'octets que je suis capable d'afficher l'image dans mon application VC++ MFC. –

+0

C'est pourquoi je ne suis pas si sûr que c'est le même tableau d'octets. Les tailles de fichier sont-elles les mêmes? –

+0

L'application VC++ affiche des images en direct de la caméra et, par conséquent, ce que j'ai fait était d'écrire le tableau d'octets dans un fichier txt. De même, à partir de mon .NET appln j'ai écrit le tableau d'octets dans un fichier nad puis comparé ces deux fichiers. Je trouve que toutes les valeurs sont remplies et elles sont plus ou moins les mêmes. –

3

J'ai eu ce problème lors de cette opération:

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

Avec les 2 dernières lignes étant le problème.Je l'ai fixé en faisant ceci:

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

Et cela a fonctionné:

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

Peut-être que l'image est intégrée dans un champ OLE et vous devez considérer l'en-tête OLE 88 octets plus une charge utile:

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

Dans mon cas, j'ai seulement dû "enlever" 8 octets. nouveau MemoryStream (byteBlobData, 8, byteBlobData.Length - 8); – iwhp

+3

Comment pourriez-vous savoir que c'était 8 bits de long? – C4u

7

Image.FromStream() attend un flux contenant UNIQUEMENT une image!

Il remet à zéro le stream.Position à 0. J'ai vous avez un flux qui contient plusieurs images ou d'autres choses, vous devez lire vos données d'image dans un tableau d'octets et d'initialiser un MemoryStream avec qui:

Image.FromStream(new MemoryStream(myImageByteArray));

le MemoryStream doit rester ouverte aussi longtemps que l'image est en cours d'utilisation.

J'ai aussi parlé de ça à la dure. :)

0

ce code fonctionne

 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

Essayez ceci:

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

it helps!

0

Essayez d'utiliser quelque chose de similaire à ce qui est décrit ici 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; 
}