C# System.ArgumentException:参数无效

C# System.ArgumentException:参数无效,c#,asp.net,image-processing,C#,Asp.net,Image Processing,我有一个页面,它将编码为base64 bmp图像(使用此算法)的html5画布数据发送到服务器端进程,该进程将其转换为System.Drawing.image对象并对其执行一些操作 在我的本地环境中,这工作正常,但在我的ec2实例中,我得到以下错误: System.ArgumentException:参数无效。在 System.Drawing.Image.FromStream(Stream-Stream,布尔值 使用EmbeddedColorManagement,Boolean validate

我有一个页面,它将编码为base64 bmp图像(使用此算法)的html5画布数据发送到服务器端进程,该进程将其转换为System.Drawing.image对象并对其执行一些操作

在我的本地环境中,这工作正常,但在我的ec2实例中,我得到以下错误:

System.ArgumentException:参数无效。在 System.Drawing.Image.FromStream(Stream-Stream,布尔值 使用EmbeddedColorManagement,Boolean validateImageData)在 System.Drawing.Image.FromStream(Stream-Stream,布尔值 使用嵌入式颜色管理)

我的代码如下所示:

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);
}
...
下面是一个文本文件,其中包含一个示例B64字符串,我正在使用该字符串进行测试:

我还尝试了以下方法,得到了相同的结果:

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

如有任何见解,将不胜感激

我仍然不知道问题的真正原因,但我猜这与
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;
    }
}
位图获取位图(字节[]buf) { Int16宽度=位转换器.ToInt16(buf,18); Int16高度=位转换器.ToInt16(buf,22); 位图位图=新位图(宽度、高度); int imageSize=宽度*高度*4; int headerSize=位转换器.ToInt16(buf,10); System.Diagnostics.Debug.Assert(imageSize==buf.Length-headerSize); int offset=headerSize; 对于(int y=0;y发布的代码似乎正确。我已经测试过了,效果很好

异常“System.ArgumentException:Parameter is not valid.”在没有任何其他提示(尤其是参数名称)的情况下,是GDI+(.NET Image类背后的底层技术)标准错误的包装,该错误无法准确告诉use哪些参数无效

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


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

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

您在本地和ec2实例上运行此框架的哪个版本?您的意思是实际测试数据(该文件)不能在ec2实例上解码,但可以在您的开发机器上解码吗?例如,您的开发和服务器测试中不可能处理不同的数据。抱歉,忘记在两者上都提到.NET 4.0。正确,测试数据可以在本地解码,但不能在ec2实例上解码。这不太可能是问题的原因,但您不应该在此处使用
using
。位于的文档说,“您必须在映像的生命周期内保持流的打开状态。”
因此我猜您提供的输入流有时作为映像无效?
您对示例数据有何看法?Image类加载失败,但我认为它在某种程度上是正确的。@L.B-我可以成功地将示例数据(OP提供的链接)加载为.BMP。但是我不能使用XP Home(32位)。我得到了相同的错误
参数无效
@L.B-有趣。也许GDI+版本不一样,所以它不支持输入图像数据。我认为——除非有人提出更好的解决方案——使用条件编译或尝试同时加载图像(
GetBitmap
image.FromStream
)函数将是最好的解决方案。谢谢!这让我更接近了。通过-R和B交换,结果输出确实改变了颜色?原始:输出:(注意:黑色背景可能是因为画布数据转换)源?不,是我编的。我不知道原始图像。因此,您必须像下面这样使用SetPixel
bitmap.SetPixel(x,height-y-1,Color.FromArgb(buf[offset+3],buf[offset+2],buf[offset+1],buf[offset])注意:我交换了
buf[offset+2]
buf[offset]
awesome!非常感谢,就这样。你有算法参考或位图数据规范我可以审查吗?我讨厌使用我不完全理解的代码。我必须承认,我对图像格式等一无所知。我用二进制编辑器打开二进制数据并试图猜测。如果你做同样的事情,你会发现前70-80个字节似乎与其他的不同。所以,我想这一定是标题,等等…等等。。。很快,颜色在文件中用4个字节表示。R-G-B-Alpha