2009-03-24 57 views
8

Estoy capturando imágenes de una cámara inteligente y recibiendo la matriz de bytes de la cámara a través de la programación del socket (la aplicación .NET es el cliente, la cámara es el servidor).El método Image.FromStream() devuelve la excepción de argumento no válido

El problema es que obtengo la excepción System.InvalidArgument en tiempo de ejecución.

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

He buscado este problema en muchos foros y he probado las sugerencias de muchos expertos, pero nada ha ayudado.

No creo que haya ningún problema con la matriz de bytes como tal, porque cuando introduzco la misma matriz de bytes en mi aplicación de cliente VC++ MFC, obtengo la imagen. Pero esto de alguna manera no funciona en C# .NET.

¿Alguien me puede ayudar?

PS:

Otros métodos que he tratado de realizar la misma tarea son:

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

Ninguno de los métodos anteriores trabajó. Amablemente ayuda.

+0

¿Qué pasa si simplemente escribe el bytearray a un archivo en el disco? ¿El archivo puede abrirse con algo como photoshop? – Chris

+1

lo has resuelto? Tengo el mismo problema – robob

Respuesta

1

System.InvalidArgument means La secuencia no tiene un formato de imagen válido, es decir, un tipo de imagen que no es compatible.

+1

Hola, Gracias por la respuesta. ¿Pero por qué funciona la misma matriz de bytes en mi aplicación VC++ MFC? También, ¿hay alguna manera de que pueda verificar la validez de mis datos de imagen de matriz de bytes? Arvind K –

0

He tenido el mismo problema en el pasado y fue causado por una fuga dentro de las bibliotecas de Windows GDI, que es lo que utiliza 'Bitmap'. Si esto sucede todo el tiempo para usted, entonces es probable que no esté relacionado, sin embargo.

+0

Hola Chris, Gracias por la respuesta. Me pasa cada vez que ejecuto el código. –

3

Supongo que algo va mal cuando recibo el archivo del servidor. ¿Tal vez solo está obteniendo parte del archivo antes de tratar de convertirlo a Image? ¿Está seguro es exactamente la misma matriz de bytes que está alimentando la aplicación C++?

Intente guardar la secuencia en un archivo y vea lo que obtiene. Es posible que puedas descubrir algunas pistas allí.

También puede agregar un punto de interrupción y comparar manualmente algunos de los bytes en la matriz de bytes a lo que se supone que deben ser (si lo sabe).


Editar: Parece que no hay nada de malo en recibir los datos. El problema es que está en formato sin formato (no es un formato que Image.FromStream entiende). El Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr) constructor puede ser útil aquí. O bien, puede crear el mapa de bits en blanco y blt hacerlo manualmente desde los datos sin procesar.

+0

Hola, He intentado guardar la imagen en un archivo jpg, bmp pero no consigo la imagen en el archivo. Lo que resulta desconcertante es que es con la misma matriz de bytes que puedo mostrar la imagen en mi aplicación VC++ MFC. –

+0

Es por eso que no estoy tan seguro de que sea la misma matriz de bytes. ¿Los tamaños de archivo son los mismos? –

+0

La aplicación VC++ muestra imágenes en vivo de la cámara y, por lo tanto, lo que hice fue escribir la matriz de bytes en un archivo txt. Del mismo modo, desde mi aplicación .NET, escribí la matriz de bytes en un archivo nad y luego comparé estos dos archivos. Encuentro que todos los valores están llenos y son más o menos lo mismo. –

3

que he tenido este problema cuando se hace esto:

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

Con las últimas 2 líneas causa de los problemas.Me fijo que al hacer esto:

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

Y entonces esto funcionó:

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

Tal vez la imagen está incrustado en un campo OLE y usted tiene que considerar el encabezado OLE 88 bytes más la carga útil:

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

En mi caso, solo tuve que "eliminar" 8 bytes. nuevo MemoryStream (byteBlobData, 8, byteBlobData.Length - 8); – iwhp

+3

¿Cómo podrías saber que tenía 8 bits de largo? – C4u

7

Image.FromStream() espera una transmisión que contiene SOLO una imagen!

Se restablece el stream.Position a 0. He haya una corriente que contiene varias imágenes u otras cosas, hay que leer los datos de imagen en una matriz de bytes y para inicializar un MemoryStream con eso:

Image.FromStream(new MemoryStream(myImageByteArray));

el MemoryStream tiene que permanecer abierta mientras la imagen está en uso.

Lo he planteado de la manera difícil también. :)

0

este código está trabajando

 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

Prueba esto:

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

Espero que ayude!

0

intenta utilizar algo similar a lo que se describe aquí 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; 
} 
Cuestiones relacionadas