2011-09-23 968 views
8

我有一个页面发送html5画布数据,编码为base64 bmp图像(使用此算法http://devpro.it/code/216.html)到服务器端进程,该进程将其转换为System.Drawing.Image对象,并执行对它进行一些操作。System.ArgumentException:参数无效

在我当地的环境,这个工作得很好,但在我的EC2实例我得到以下错误:

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)

我的代码如下:

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

这里是一个文本文件一个样本b64string,我正在测试:https://docs.google.com/leaf?id=0BzVLGmig1YZ3MTM0ODBiNjItNzk4Yi00MzI5LWI5ZWMtMzU1OThlNWEyMTU5&hl=en_US

我也试过以下,并有相同的结果:

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

任何有识之士将不胜感激!

+0

您在本地和ec2实例上运行此框架的哪个版本? – Oded

+0

您的意思是说实际测试数据(该文件)无法在ec2实例上解码,但可以在您的开发机器上?例如。在开发和服务器测试中不可能有不同的数据被处理。 –

+0

对不起,忘了提及.NET 4.0。 – ari

回答

5

我仍然不知道你的问题的真正原因,但我想它是关联的图像格式,其中Image类不承认。稍微检查二进制数据之后,我可以形成图像。我希望这有帮助。

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

谢谢!这让我更加接近。结果输出确实会改变颜色 - R和B交换? 原创:http://i.imgur.com/a0UXf.gif 输出:http://i.imgur.com/TVUmk.gif (注:黑色背景可能是因为画布数据转换) – ari

+0

你有解码代码的来源? – ari

+0

来源?不,我做到了。我不知道原始图像。所以,你要玩一点点,像这样'bitmap.SetPixel(X,高度SetPixel - Y - 1,Color.FromArgb(BUF [偏移+ 3],BUF [偏移+ 2],BUF [偏移+1] ,BUF [偏移]));'注:我交换'的buf [偏移+ 2]'和'BUF [偏移]' –

3

发布的代码似乎是正确的。我已经测试过它,它工作正常。

异常 “System.ArgumentException:参数是无效的。”没有任何其他提示(特别是不是参数的名称)是GDI +(.NET Image类背后的基础技术)标准的InvalidParameter错误的包装,它不会告诉使用何种参数无效。

因此,在使用.NET Reflector的FromStream代码之后,我们可以看到GDI +调用中使用的参数本质上......输入流。

所以我的猜测是,你所提供的输入流有时为图像无效?您应该保存失败的输入流(例如使用File.SaveAllBytes(sf))以供进一步调查。

+0

'所以我的猜测是,你所提供的输入流是无效的,有时作为一个形象呢?'你觉得什么样的数据?图像类无法加载,但我认为这是正确的。 –

+0

@ L.B - 我可以成功地将样例数据(由OP给出的链接)作为.BMP加载。 –

+0

但我不能用我的XP-Home(32位)。我得到同样的错误'参数无效' –

0

这可能发生,如果sf包含无效的图像数据。验证您传递到数据流中的数据的有效性,并查看是否解决了您的问题。