2011-09-23 163 views
8

Tengo una página que envía datos de lienzo html5, codificados como una imagen base bmp (utilizando este algoritmo http://devpro.it/code/216.html) a un proceso del lado del servidor que lo convierte en un objeto System.Drawing.Image y lo hace algunas operaciones en él.System.ArgumentException: El parámetro no es válido

En mi entorno local, esto funciona muy bien, pero en mi instancia EC2 me sale el siguiente error:

System.ArgumentException: Parameter is not valid. at System.Drawing.Image.FromStream(Stream stream, Boolean useEmbeddedColorManagement, Boolean validateImageData) at System.Drawing.Image.FromStream(Stream stream, Boolean useEmbeddedColorManagement)

Mi código es el siguiente:

System.Drawing.Image image = null; 
string b64string = "..."; 
byte[] sf = Convert.FromBase64String(b64string); 
using (MemoryStream s = new MemoryStream(sf, 0, sf.Length)) 
{ 
    image = System.Drawing.Image.FromStream(s, false); 
} 
... 

Aquí hay un archivo de texto con una muestra b64string que estoy utilizando para probar: https://docs.google.com/leaf?id=0BzVLGmig1YZ3MTM0ODBiNjItNzk4Yi00MzI5LWI5ZWMtMzU1OThlNWEyMTU5&hl=en_US

También he intentado lo siguiente y tuve los mismos resultados:

System.Drawing.ImageConverter converter = new System.Drawing.ImageConverter(); 
image = converter.ConvertFrom(sf) as System.Drawing.Image;   

¡Cualquier observación sería muy apreciada!

+0

¿En qué versión del framework está ejecutando esto de forma local y en la instancia de ec2? – Oded

+0

¿Quiere decir que los datos de prueba reales (ese archivo) no se pueden decodificar en la instancia de ec2, pero pueden estar en su máquina de desarrollo? P.ej. no hay posibilidad de que se procesen datos diferentes en su desarrollador y en su prueba de servidor. –

+0

Lo sentimos, olvidé mencionar .NET 4.0 en ambos. – ari

Respuesta

5

Todavía no conozco la verdadera causa de su problema, pero supongo que está relacionado con un formato de imagen que la clase Image no reconoce. Después de inspeccionar un poco los datos binarios, podría formar su imagen. Espero que esto ayude.

Bitmap GetBitmap(byte[] buf) 
{ 
    Int16 width = BitConverter.ToInt16(buf, 18); 
    Int16 height = BitConverter.ToInt16(buf, 22); 

    Bitmap bitmap = new Bitmap(width, height); 

    int imageSize = width * height * 4; 
    int headerSize = BitConverter.ToInt16(buf, 10); 

    System.Diagnostics.Debug.Assert(imageSize == buf.Length - headerSize); 

    int offset = headerSize; 
    for (int y = 0; y < height; y++) 
    { 
     for (int x = 0; x < width; x++) 
     { 
      bitmap.SetPixel(x, height - y - 1, Color.FromArgb(buf[offset + 3], buf[offset], buf[offset + 1], buf[offset + 2])); 
      offset += 4; 
     } 
    } 
    return bitmap; 
} 

private void Form1_Load(object sender, EventArgs e) 
{ 
    using (FileStream f = File.OpenRead("base64.txt")) 
    { 
     byte[] buf = Convert.FromBase64String(new StreamReader(f).ReadToEnd()); 

     Bitmap bmp = GetBitmap(buf); 
     this.ClientSize = new Size(bmp.Width, bmp.Height); 
     this.BackgroundImage = bmp; 
    } 
} 
+0

Gracias! esto me acerca mucho más. Sin embargo, el resultado resultante cambia los colores: ¿R y B intercambiados? Original: http://i.imgur.com/a0UXf.gif Salida: http://i.imgur.com/TVUmk.gif (nota: el fondo negro puede ser debido a la conversión de datos del lienzo) – ari

+0

Do usted tiene una fuente para el código de decodificación? – ari

+0

Fuente? No, lo inventé. No sé la imagen original. Entonces, tienes que jugar un poco con SetPixel como este 'bitmap.SetPixel (x, height - y - 1, Color.FromArgb (buf [offset + 3], buf [offset + 2], buf [offset + 1] , buf [offset])); 'Nota: he cambiado' buf [offset + 2] 'y' buf [offset] ' –

3

El código publicado parece correcto. Lo he probado y funciona bien.

La excepción "System.ArgumentException: El parámetro no es válido". sin ninguna otra sugerencia (especialmente no el nombre del parámetro) es un contenedor para GDI + (la tecnología subyacente detrás de la clase de imagen .NET) InvalidParameter error estándar, que no indica exactamente qué parámetro no es válido.

Por lo tanto, siguiendo el código FromStream con .NET Reflector, podemos ver que los parámetros utilizados en las llamadas GDI + son esencialmente ... el flujo de entrada.

Así que supongo que el flujo de entrada que proporcione a veces no es válido como imagen. Debería guardar las secuencias de entrada que fallan (usando File.SaveAllBytes (sf) por ejemplo) para una investigación más a fondo.

+0

'¿Entonces supongo que el flujo de entrada que proporciona a veces no es válido como imagen? ¿Qué opina de los datos de muestra? La clase de imagen no se carga, pero creo que de alguna manera es correcta. –

+0

@ L.B - Puedo cargar datos de muestra (el enlace proporcionado por el OP) como .BMP con éxito. –

+0

Pero no puedo con mi XP-Home (32 bits). Me sale el mismo error 'El parámetro no es válido' –

0

Esto podría suceder si sf contenía datos de imagen no válidos. Verifique la validez de los datos que está enviando a la transmisión y vea si eso soluciona el problema.

Cuestiones relacionadas