Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.ArgumentException: Parameter is not valid

I have a page that sends html5 canvas data, encoded as a base64 bmp image (using this algorithm http://devpro.it/code/216.html) to a serverside process that converts it into a System.Drawing.Image object and does some operations on it.

In my local environment, this works just fine, but on my ec2 instance I get the following 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)

My code looks as follows:

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

Here's a text file with a sample b64string that I'm using to test: https://docs.google.com/leaf?id=0BzVLGmig1YZ3MTM0ODBiNjItNzk4Yi00MzI5LWI5ZWMtMzU1OThlNWEyMTU5&hl=en_US

I've also tried the following and had the same results:

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

Any insight would be greatly appreciated!

like image 598
ari Avatar asked Sep 23 '11 19:09

ari


2 Answers

I still don't know the real cause of your problem, but i guess it is related with a image format which Image class doesn't recognize. After inspecting the binary data a little bit, I could be able to form your image. I hope this helps.

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;
    }
}
like image 70
L.B Avatar answered Nov 13 '22 14:11

L.B


The posted code seems correct. I have tested it and it works fine.

The exception "System.ArgumentException: Parameter is not valid." without any other hint (especially not the name of the parameter) is a wrapper for GDI+ (the underlying technology behind .NET Image class) standard InvalidParameter error, which does not tell use exactly what parameter is invalid.

So, following the FromStream code with .NET Reflector, we can see that the parameters used in GDI+ calls are essentially ... the input stream.

So my guess is the input stream you provide is sometimes invalid as an image? You should save the failing input streams (using File.SaveAllBytes(sf) for example) for further investigation.

like image 32
Simon Mourier Avatar answered Nov 13 '22 14:11

Simon Mourier