2

I have an application that asks users to upload a photo via flash. Flash then turns this photo into a byte array. Here is that code:

 var rect:Rectangle=new Rectangle(0,0,imageWidth,imageHeight);

// create BitmapData
var bmd:BitmapData=new BitmapData(imageWidth,imageHeight,true,0);
bmd.draw(myMovieClip);// get the image out of the MovieClip

// create byte array
var binaryData:ByteArray = new ByteArray();
binaryData.position=0;// start at the beginning
binaryData.writeBytes(bmd.getPixels(rect));

After the byte array is created, it is base64 encoded and posted to an IIS server that houses an .ashx handler. In the handlers ProcessRequest method the following code is used to write the data out to a file:

  try
  {
      // Convert from base64string to binary array and save
      byte[] contents = Convert.FromBase64String(encodedData); //encodedData is the Base64 encoded byte array from flash
      File.WriteAllBytes(fullPath, (byte[])contents);
      context.Response.Write("result=1");
  }
  catch (Exception ex) 
  { 
     context.Response.Write("errMsg=" + ex.Message + "&result=0"); 
  }

So far so good. No problems up to this point.

The problem occurs after retrieving the byte data that is stored in the file and attempting to recreate the image on the server side in C#.

When I try the following:

try
{
    var fileBytes = File.ReadAllBytes(path);
    Bitmap bmp;
    using (var ms = new MemoryStream(fileBytes))
    {
        ms.Position = 0;
        using (var i = Image.FromStream(ms, false, true))
        {
        bmp = new Bitmap(i);
        }
    }
}
catch (Exception ex)
{
    //error: ex.Message is always “the parameter is not valid”
}

The program always throws on this line with the message “the parameter is not valid”

using (var i = Image.FromStream(ms, false, true))

Any advice is greatly appreciated.

4
  • 2
    When attempting to read the image, I'd try Image.FromFile instead to avoid writing so much code. But first: can you open the saved file in an image viewer (e.g. Paint)? Commented Jan 25, 2013 at 19:07
  • No, I cannot. Here is something odd tho, The flash app also has the ability to make a call to the web server and get the byte array and it CAN recreate and display the image. Commented Jan 25, 2013 at 19:49
  • why are you doing "Convert.FromBase64String" Commented Jan 25, 2013 at 21:34
  • becuase the data is base64 encoded before it is posted to the server Commented Jan 26, 2013 at 21:02

2 Answers 2

3

BitmapData.getPixels() is just a ByteArray of 32 bit uint values (ARGB) for each pixel, are you sure C# Image.FromStream can handle such format correct? As an alternative you can encode your image to PNG or JPG bytes (there are several PNG/JPG encoders, flex version or as3corelib)

Sign up to request clarification or add additional context in comments.

1 Comment

While your answer was exactly "the answer", it did lead me directly to the answer as shown below. Thanks much.
0

Its turns out that fsbmain is correct above. Image.FromStream does not have the ability to take the data from BitmapData.getPixels() and create an image from it.

In order to get back to the original image, I needed to use Bitmap.SetPixel() and loop thru the byte array setting the ARGB values as shown below:

(please note that the height and width are prepended to the byte array. Thats why I'm using Buffer.BlockCopy to split the array up into the parts that I need)

static void Main(string[] args)
            {
                string path = @"C:\data\TUIxMTA0ODM5\imagea.b64";
                string imagepath = @"C:\data\newPic.jpg";

                try
                {
                    //get the data from the file
                    var f = File.ReadAllBytes(path);

                    //get the height and width of the image
                    var newArr = new byte[4];
                    Buffer.BlockCopy(f, 0, newArr, 0, 4);
                    var height = ReadShort(newArr, 0);
                    var width = ReadShort(newArr, 2);

                    //get the pixel data
                    var myArr = new byte[f.Length - 4];
                    Buffer.BlockCopy(f, 4, myArr, 0, f.Length - 4);

                    //create the new image
                    var bmp = new Bitmap(width, height);
                    int counter = 0;
                    for (int x = 0; x < width; x++)
                    {
                        for (int y = 0; y < height; y++)
                        {
                            bmp.SetPixel(x, y, Color.FromArgb(myArr[counter], myArr[++counter], myArr[++counter], myArr[++counter]));
                            counter++;
                        }
                    }
                    bmp.Save(imagepath, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }

            public static short ReadShort(byte[] buffer, int offset)
            {
                return (short)((buffer[offset + 0] << 8) + buffer[offset + 1]);
            }

I hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.