tags:

views:

60

answers:

2

I want to read the raw binary of a PNG file on a website and store it into a byte[], so far I have something like this:

            Uri imageUri = new Uri("http://www.example.com/image.png");
            // Create a HttpWebrequest object to the desired URL.
            HttpWebRequest imgRequest = (HttpWebRequest)WebRequest.Create(imageUri);
                using (HttpWebResponse imgResponse = (HttpWebResponse)imgRequest.GetResponse())
            {
                using (BinaryReader lxBR = new BinaryReader(imgResponse.GetResponseStream()))
                {
                    using (MemoryStream lxMS = new MemoryStream())
                    {
                        lnBuffer = lxBR.ReadBytes(1024);
                        while (lnBuffer.Length > 0)
                        {
                            lxMS.Write(lnBuffer, 0, lnBuffer.Length);
                            lnBuffer = lxBR.ReadBytes(1024);
                        }
                        lnFile = new byte[(int)lxMS.Length];
                        lxMS.Position = 0;
                        lxMS.Read(lnFile, 0, lnFile.Length);
                    }
                }
            }

but I can't use GetResponse on Silverlight because it is not Asynchronous (I think that's the reason) so instead I should be using BeginGetResponse, but I'm not completely clear on how to go about it. This is what I have so far:

                HttpWebResponse imgResponse = (HttpWebResponse)imgRequest.BeginGetResponse(new AsyncCallback(WebComplete), imgRequest);

            using (imgResponse)
            {
                using (BinaryReader lxBR = new BinaryReader(imgResponse.GetResponseStream()))
                {
                    /*Same*/
                }
            }

and

        void WebComplete(IAsyncResult a)
    {
        HttpWebRequest req = (HttpWebRequest)a.AsyncState;
        HttpWebResponse res = (HttpWebResponse)req.EndGetResponse(a);
        //...? Do I need something else here?
    }

can someone explain me a little bit how to use the BeginGetResponse property and how do I use the AsyncCallback. Thanks!

Note: I'm new to silverlight and I've been following tutorials and borrowing from other responses here on StackOverflow: (stackoverflow responce) what I need to do but not in silverlight

tutorial

WebRequest_in_Silverlight

is this valid Silverlight code?

HttpWebResponse imgResponse = (HttpWebResponse)imgRequest.BeginGetResponse(new AsyncCallback(WebComplete), imgRequest);
A: 

Use the OpenReadAsync method of the WebClient object. Attach to the OpenReadCompleted event of the WebClient. Use the Stream provided by the Result property of the event args.

Consider setting AllowReadStreamBuffering, this will fill the entire stream before raising the OpenReadCompleted. In either case its likely you can use this stream to complete you real task rather than coping it into a MemoryStream.

AnthonyWJones
so use WebClient instead of HttpWebRequest? I'll do a little research on those then. Thanks
david
Well it looks like I can't use HttpWebRequest anyways the HttpWebRequest.BeginGetResponse() gives me a runtime error
david
@david: You can use HttpWebRequest within Silverlight (internally thats what WebClient uses) however WebClient is far simpler in many cases.
AnthonyWJones
A: 

Got it working, want to post it here in case anyone needs it.

I need to get this image and then modify it (byte level) Silverlight didn't let me save the image directly to a WriteableBitmap and thus I had to get the image with a WebClient as a stream and then save it to a byte[]

this is how I get the image (I already have the specific Uri):

 WebClient wc = new WebClient();
 wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
 wc.OpenReadAsync(uri)

so when the image is loaded the wc_OpenReadCompleted method is called and it does something like this:

int lengthInBytes = Convert.ToInt32(e.Result.Length);
BinaryReader br = new BinaryReader(e.Result);

byte[] buffer = new byte[lengthInBytes];
using (br)
{
    for (int i = 0; i < lengthInBytes; i++)
    {
        buffer[i] = br.ReadByte();
    }
}

at the end the buffer[] has all the bytes of the image (what I wanted) I'm sure there are better ways of doing this but this is working for me ! )

note: at some point I need to convert the byte[] to a BitmapImage (that was easier than expected):

        //imageInBytes is a byte[]

        if (imageInBytes != null)
        {
            MemoryStream rawBytesStream = new MemoryStream(imageInBytes);
            BitmapImage img = new BitmapImage();
            img.SetSource(rawBytesStream);
            return img;
        }

I hope this helps anyone.

david
Oh and if anyone has any suggestion, please do post them!
david