2011-09-23 13 views
8

Ho una pagina che invia dati canvas html5, codificati come immagine bmp base64 (utilizzando questo algoritmo http://devpro.it/code/216.html) a un processo serveride che la converte in un oggetto System.Drawing.Image e lo fa alcune operazioni su di esso.System.ArgumentException: Parametro non valido

Nel mio ambiente locale, questo funziona bene, ma la mia istanza EC2 ottengo il seguente errore:

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)

Il mio codice si presenta come segue:

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

Ecco un file di testo con un esempio di b64string che sto usando per testare: https://docs.google.com/leaf?id=0BzVLGmig1YZ3MTM0ODBiNjItNzk4Yi00MzI5LWI5ZWMtMzU1OThlNWEyMTU5&hl=en_US

Ho anche provato quanto segue e ho avuto gli stessi risultati:

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

Qualsiasi intuizione sarebbe molto apprezzata!

+0

Quale versione del framework si sta eseguendo su, localmente e sull'istanza di ec2? – Oded

+0

Vuoi dire che i dati di test effettivi (quel file) non possono essere decodificati sull'istanza di ec2, ma possono essere sulla tua macchina di sviluppo? Per esempio. non c'è alcuna possibilità che ci siano dati differenti elaborati nel tuo dev e nel test del tuo server. –

+0

Mi dispiace, ho dimenticato di menzionare .NET 4.0 su entrambi. – ari

risposta

5

Ancora non conosco la vera causa del problema, ma suppongo che sia correlato a un formato di immagine che la classe Image non riconosce. Dopo aver ispezionato un po 'i dati binari, potrei essere in grado di formare la tua immagine. Spero che aiuti.

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

Grazie! questo mi avvicina molto. L'output risultante cambia però i colori - R e B invertiti? Originale: http://i.imgur.com/a0UXf.gif Output: http://i.imgur.com/TVUmk.gif (nota: lo sfondo nero potrebbe essere dovuto alla conversione dei dati su tela) – ari

+0

Do hai una fonte per il codice di decodifica? – ari

+0

Fonte? No, l'ho inventato Non conosco l'immagine originale. Quindi, devi giocare un po 'con SetPixel come questo 'bitmap.SetPixel (x, height - y - 1, Color.FromArgb (buf [offset + 3], buf [offset + 2], buf [offset + 1] , buf [offset])); 'Nota: ho scambiato' buf [offset + 2] 'e' buf [offset] ' –

3

Il codice pubblicato sembra corretto. L'ho provato e funziona bene.

L'eccezione "System.ArgumentException: Parameter non è valido." senza alcun altro suggerimento (specialmente non il nome del parametro) è un wrapper per GDI + (la tecnologia sottostante alla classe .NET Image) standard InvalidParameter, che non dice usare esattamente quale parametro non è valido.

Quindi, seguendo il codice FromStream con .NET Reflector, possiamo vedere che i parametri utilizzati nelle chiamate GDI + sono essenzialmente ... il flusso di input.

Quindi la mia ipotesi è che il flusso di input che fornisci a volte non sia valido come immagine? Dovresti salvare i flussi di input in errore (usando File.SaveAllBytes (sf) per esempio) per ulteriori indagini.

+0

'Quindi la mia ipotesi è che il flusso di input che fornisci a volte non sia valido come immagine?' Cosa ne pensi dei dati di esempio? La classe immagine non viene caricata, ma penso che sia in qualche modo corretta. –

+0

@ L.B - Posso caricare correttamente i dati di esempio (il collegamento fornito dall'OP) come .BMP. –

+0

Ma non posso con la mia XP-Home (32 bit). Ottengo lo stesso errore "Il parametro non è valido" –

0

Questo potrebbe accadere se sf contenesse dati di immagini non validi. Verifica la validità dei dati che stai trasmettendo nello stream e verifica se questo risolve il problema.

Problemi correlati